puttykey

package
v0.714.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package puttykey parses a PuTTY private key file (the ".ppk" / "PuTTY-User-Key-File-N" format) for triage. A saved PuTTY / WinSCP / FileZilla key is the Windows counterpart to a stolen id_ed25519 — top pentest loot — and the first questions are the same as for an OpenSSH key (see internal/sshkey): is it **encrypted** (so the passphrase must be cracked — putty2john + John the Ripper — before use)? what **key type**? what **SHA256 fingerprint** (to correlate the key with an authorized_keys entry / a known target identity)? and what **comment**? Unlike OpenSSH, a PPK's comment is a cleartext header so it is readable even for an encrypted key. Pure offline transform; no network or device.

Wrap-vs-native judgement

Native. The .ppk format is a simple line-based text container (RFC-822-style "Key: value" headers wrapping two base64 blocks), documented in the PuTTY manual appendix. The public block is base64 of the **same SSH-wire public blob** that goes in an authorized_keys line, so the type + fingerprint are a base64-decode + a length-prefixed read + a SHA-256 — there is nothing to wrap. Pulling in a third-party PPK library (none is in go.mod) would add a runtime dep for what is a few dozen lines of text parsing. Consistent with the other in-tree key/loot parsers.

Verifiable / no confidently-wrong output

The key-type + fingerprint are cross-validated against `ssh-keygen`: a PPK's Public-Lines base64 is byte-for-byte the same SSH-wire blob as the matching OpenSSH .pub, so SHA256(blob) reproduces `ssh-keygen -l`'s exact SHA256 fingerprint (confirmed for a generated ed25519 and rsa key). The header fields (version, Encryption, Comment, Key-Derivation, Argon2-*, Private-MAC) are plain-text reads against the documented PuTTY AppendixC format — no transform that could be confidently wrong. The Private-Lines section (PuTTY's own private-key layout) and the Private-MAC are surfaced/raw, not decoded or verified: MAC verification needs the passphrase-derived key, and a wrong "valid/invalid" verdict would be worse than none. A blob that does not begin with the PuTTY-User-Key-File- magic, or whose public block is missing / undecodable, is rejected.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	Format            string `json:"format"`     // always "ppk"
	Version           int    `json:"version"`    // 1, 2, or 3
	Algorithm         string `json:"algorithm"`  // from the header line, e.g. ssh-ed25519
	Encryption        string `json:"encryption"` // none / aes256-cbc
	Encrypted         bool   `json:"encrypted"`
	KeyType           string `json:"key_type"`    // from the public blob (should match algorithm)
	Fingerprint       string `json:"fingerprint"` // SHA256:... (as `ssh-keygen -l` prints)
	Comment           string `json:"comment,omitempty"`
	KeyDerivation     string `json:"key_derivation,omitempty"` // Argon2id / Argon2i / Argon2d (v3 encrypted)
	Argon2Memory      int    `json:"argon2_memory_kb,omitempty"`
	Argon2Passes      int    `json:"argon2_passes,omitempty"`
	Argon2Parallelism int    `json:"argon2_parallelism,omitempty"`
	Argon2SaltLen     int    `json:"argon2_salt_len,omitempty"`
	PrivateMAC        string `json:"private_mac,omitempty"`
	Note              string `json:"note,omitempty"`
}

Result is the triage view of a PuTTY .ppk private key file.

func Decode

func Decode(in string) (*Result, error)

Decode parses a PuTTY .ppk private key file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL