Documentation
¶
Overview ¶
Package pemkey parses a PEM private key file (the openssl-style "-----BEGIN [RSA|EC|ENCRYPTED] PRIVATE KEY-----" / PKCS#1 / SEC1 / PKCS#8 formats) for triage. A stolen .pem / .key file is top pentest loot (TLS server keys, client-cert keys, API keys), and the first questions mirror the OpenSSH and PuTTY key tools (see internal/sshkey, internal/puttykey): is it **encrypted** (so the passphrase must be cracked before use)? what **key algorithm + size** (an RSA-1024 / weak key is worth flagging)? for an unencrypted key, what **public-key SHA-256** (to correlate the key with a known certificate / endpoint)? and for an encrypted key, what **cipher + KDF** (the crack cost)? Pure offline transform; no network or device.
Wrap-vs-native judgement ¶
Native (own code + Go stdlib; no third-party dep, no shell-out). The unencrypted-key DER is parsed with crypto/x509 (ParsePKCS1PrivateKey / ParseECPrivateKey / ParsePKCS8PrivateKey) and crypto/x509.MarshalPKIXPublicKey — these are stdlib ASN.1/DER routines for exactly these standard key structures; hand-rolling RSA/EC DER parsing would reinvent stdlib poorly and risk a confidently-wrong decode. The part stdlib will NOT do without the passphrase — reading the cipher + KDF parameters out of an encrypted key — is hand-rolled here: the traditional Proc-Type/DEK-Info headers are a plain-text read, and the PKCS#8 EncryptedPrivateKeyInfo (PBES2 → PBKDF2 / scrypt + an encryption scheme) is walked with encoding/asn1. No PEM/PKCS library is added to go.mod. Consistent with the other in-tree key/loot parsers.
Verifiable / no confidently-wrong output ¶
Anchored to openssl: for a generated EC P-256, Ed25519 and RSA-1024 key the algorithm / curve / bits + the public-key SHA-256 reproduce `openssl pkey -pubout -outform DER | sha256sum` exactly; for an encrypted key the cipher / KDF / salt / iteration (PBKDF2) or N,r,p (scrypt) / IV-length reproduce `openssl asn1parse` exactly. Every recognised OID is vector-checked; an unrecognised algorithm/cipher/KDF/PRF OID is surfaced as its dotted string with "(unrecognized)" rather than guessed. The key type/size of an encrypted key live in the ciphertext and are reported as unavailable, never guessed. A non-PEM blob, or DER that fails to parse, is rejected. An OpenSSH-format key is redirected to ssh_privkey_decode.
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"` // pem-pkcs1 / pem-sec1 / pem-pkcs8 / pem-traditional-encrypted / pem-pkcs8-encrypted
PEMType string `json:"pem_type"` // the BEGIN label
Algorithm string `json:"algorithm,omitempty"`
Bits int `json:"bits,omitempty"`
Curve string `json:"curve,omitempty"`
Encrypted bool `json:"encrypted"`
Cipher string `json:"cipher,omitempty"`
IVLen int `json:"iv_len,omitempty"`
KDF string `json:"kdf,omitempty"`
KDFPRF string `json:"kdf_prf,omitempty"`
KDFSaltLen int `json:"kdf_salt_len,omitempty"`
KDFIterations int `json:"kdf_iterations,omitempty"`
ScryptN int `json:"scrypt_n,omitempty"`
ScryptR int `json:"scrypt_r,omitempty"`
ScryptP int `json:"scrypt_p,omitempty"`
PublicSHA256 string `json:"public_sha256,omitempty"` // SHA-256 of the SubjectPublicKeyInfo DER (unencrypted only)
Note string `json:"note,omitempty"`
}
Result is the triage view of a PEM private key file.