File extensions do not tell you whether a file contains a private key, and that confusion is how private keys end up in tickets, repositories and shared drives. A .pem may hold a public certificate or an unencrypted private key; a .pfx almost always holds a key; a .cer and a .crt are usually the same thing in different encodings. This guide explains the encodings (DER and PEM), the container formats (PKCS #8, PKCS #12, PKCS #7, PuTTY PPK), how to tell what a file contains, how thumbprints and fingerprints are calculated, how to convert safely, and how to store and scan for key files. It is written for engineers who handle TLS, code signing, SSH and workload certificates, and for security teams who triage key exposure. Java keystores are covered in depth in the Java Keystores Guide, and certificate fundamentals in the PKI Basics Guide.
Key takeaways
- Encoding and content are separate questions. DER is binary and PEM is Base64 text with BEGIN and END lines; either can carry a certificate, a key or a chain.
- Read the PEM label, not the extension.
CERTIFICATEis public;PRIVATE KEY,RSA PRIVATE KEY,EC PRIVATE KEYandOPENSSH PRIVATE KEYare secrets, and onlyENCRYPTED PRIVATE KEYis protected at rest. - PFX and P12 files are key containers. PKCS #12 bundles a private key with its certificate chain behind a password, so treat every one as a secret.
- A thumbprint is a hash of the whole certificate. Windows thumbprints are SHA-1 by default; compare SHA-256 fingerprints where your tools support them, and never treat a fingerprint as proof of trust.
- Conversions are where keys leak. Exporting a PFX to PEM without encryption writes a plaintext key to disk; encrypt it, restrict it and delete intermediates.
What it is
A certificate file stores an X.509 certificate: a public key bound to a name and signed by a certificate authority. A key file stores a private key, the secret that proves possession of that certificate. Several standards define how these objects are serialised, and file extensions grew up around them by convention rather than rule. Two layers matter:
- Encoding: how the ASN.1 structure is written. DER (Distinguished Encoding Rules) is binary. PEM is the textual form defined in RFC 7468: Base64 of the DER bytes between
-----BEGIN label-----and-----END label-----lines. Text outside those lines is allowed and often contains a readable summary. - Structure: what is inside. A certificate (RFC 5280), a certificate signing request (PKCS #10), a private key in PKCS #8 or an older algorithm-specific format, a PKCS #7 or CMS bundle of certificates, or a PKCS #12 container holding keys and certificates together.
Format reference
| Format or extension | Encoding | Typical content | Contains a private key? |
|---|---|---|---|
.pem | PEM text | Anything: certificate, chain, key, CSR | Possibly: read the labels |
.crt, .cer | PEM or DER (Windows exports offer both) | A single certificate | No, by convention |
.der | DER binary | A certificate or key | Possibly |
.key | Usually PEM | A private key (PKCS #8 or traditional) | Yes |
.csr | Usually PEM | Certificate signing request (label CERTIFICATE REQUEST) | No, but its key is nearby |
.p7b, .p7c | PEM or DER | PKCS #7 certificate bundle, often a chain | No |
.pfx, .p12 | DER (binary) | PKCS #12 container: key, certificate, chain | Almost always |
.ppk | Text (PuTTY format) | PuTTY SSH key pair | Yes |
.jks, .keystore | Java-specific binary | Java keystore with keys and certificates | Usually: see the Java Keystores Guide |
id_rsa, id_ed25519 | PEM-like text | OpenSSH private key (OPENSSH PRIVATE KEY) | Yes: see the SSH Key Management Guide |
How it works
PEM labels and what they mean
RFC 7468 (Proposed Standard, April 2015) fixes the labels for standard structures. OpenSSL also reads several legacy labels for compatibility. The label is the fastest reliable way to tell a secret from a public object.
| PEM label | Structure | Secret? | Notes |
|---|---|---|---|
CERTIFICATE | X.509 certificate (RFC 5280) | No | Generators must use this rather than the old X509 CERTIFICATE |
CERTIFICATE REQUEST | PKCS #10 CSR (RFC 2986) | No | NEW CERTIFICATE REQUEST is a legacy variant |
X509 CRL | Certificate revocation list | No | |
PKCS7, CMS | ContentInfo, often a certificate bundle | No | RFC 7468 says implementations should prefer CMS where it is an option |
PUBLIC KEY | SubjectPublicKeyInfo | No | |
PRIVATE KEY | PKCS #8 PrivateKeyInfo / OneAsymmetricKey (RFC 5208, RFC 5958) | Yes, unencrypted | OpenSSL 3 writes this form by default |
ENCRYPTED PRIVATE KEY | PKCS #8 EncryptedPrivateKeyInfo (RFC 5958) | Yes, password-protected | The preferred at-rest form for a standalone key |
RSA PRIVATE KEY, EC PRIVATE KEY | Traditional algorithm-specific formats | Yes | Not defined by RFC 7468; produced by older tools or OpenSSL -traditional; may carry Proc-Type: 4,ENCRYPTED headers |
OPENSSH PRIVATE KEY | OpenSSH's own key format | Yes | May or may not be passphrase-protected; check before assuming |
RFC 7468 also says generators must not use a CERTIFICATE CHAIN label. A chain file is simply several CERTIFICATE blocks in one PEM file, conventionally the leaf (end-entity) certificate first, followed by intermediates. Servers usually need the leaf plus intermediates but not the root, which clients already hold in their trust store; see the Certificate Trust Stores Guide.
Inside a PKCS #12 (PFX or P12) file
PKCS #12 v1.1 is published as RFC 7292 (Informational, July 2014), updated by RFC 9579 and RFC 9879 to allow PBMAC1 integrity protection. The top-level structure is called a PFX. It contains SafeBags of several types:
- keyBag: a PKCS #8 private key stored unencrypted inside the container.
- pkcs8ShroudedKeyBag: a PKCS #8 private key encrypted with a password-derived key, the normal case.
- certBag and crlBag: certificates and CRLs, typically the leaf certificate and its chain.
- secretBag: any other secret.
Integrity is usually a password-based HMAC; privacy is password-based encryption. The algorithms matter. Current OpenSSL creates PKCS #12 files with AES-256-CBC and PBKDF2 by default. Older files use RC2-40 or triple DES, which OpenSSL 3 will only open with the -legacy option. A legacy PFX found on a file share is protected mainly by its password, so a weak password makes it effectively plaintext.
PuTTY PPK files
PuTTY stores SSH key pairs in its own text format. Version 3 is current; version 2 was used from PuTTY 0.52 to 0.74. The header names the algorithm, the encryption type (aes256-cbc or none) and a comment. The public key is always stored unencrypted. Version 3 derives the encryption and MAC keys from the passphrase with Argon2 and protects the file with HMAC-SHA-256; version 2 used SHA-1 based derivation and HMAC-SHA-1. A PPK with Encryption: none is a plaintext private key.
Thumbprints and fingerprints
A certificate thumbprint or fingerprint is a hash of the entire DER-encoded certificate. It is not stored in the certificate; tools compute it. OpenSSL's x509 -fingerprint option uses SHA-1 unless you name another digest (for example -sha256). In .NET, X509Certificate2.Thumbprint is always SHA-1, and GetCertHashString(HashAlgorithmName.SHA256) returns a SHA-256 value. Windows certificate stores, IIS bindings and many cloud consoles identify certificates by SHA-1 thumbprint for lookup.
- Use for: finding a certificate in a store, pinning a known certificate in configuration, and checking that two files hold the same certificate.
- Do not use for: deciding whether to trust a certificate. Trust comes from chain validation, not from a hash.
- Prefer SHA-256 wherever the tool offers it, and record which algorithm a stored fingerprint uses.
Common conversions, done safely
| Task | OpenSSL approach | Safety note |
|---|---|---|
| DER certificate to PEM | openssl x509 -inform der -in cert.cer -out cert.pem | Public data, no risk |
| Inspect a certificate | openssl x509 -in cert.pem -noout -text -fingerprint -sha256 | Read-only |
| PFX to PEM certificate only | openssl pkcs12 -in file.pfx -nokeys -out chain.pem | Use -clcerts for the leaf only |
| PFX to PEM private key | openssl pkcs12 -in file.pfx -nocerts -out key.pem | Output is encrypted unless -noenc is given (-nodes is deprecated since OpenSSL 3.0); avoid unencrypted output |
| PEM key and certificate to PFX | openssl pkcs12 -export -inkey key.pem -in cert.pem -chain -out file.pfx | Use a strong export password; add -legacy only for old consumers |
| Traditional key to PKCS #8 | openssl pkey -in old.key -out new.key (PKCS #8 is the default output) | Add a cipher option to encrypt the output |
PPK conversion is done with PuTTYgen, which can import and export OpenSSH format keys. Keep the converted key passphrase-protected.
Why it matters
Private key files are long-lived non-human credentials. A leaked TLS key lets an attacker impersonate a service until the certificate expires or is revoked; a leaked code signing key lets them sign malware; a leaked SSH or GitHub App key grants direct access. The Leaked GitHub App Private Keys 2026 research found forgotten keys that still worked, including one with write access to private repositories in a US CDC organisation. See the Private Keys in Repositories Guide for response steps.
Rolling out key file hygiene
- Inventory: scan repositories, file shares, build agents and servers for key and container extensions and for private key PEM labels; record owner and certificate for each hit.
- Triage: classify each find as public (certificate, chain, CSR) or secret, and check whether secrets are encrypted and whether their certificates are still valid.
- Contain: revoke and reissue certificates whose keys sat in shared locations, starting with code signing, internet-facing TLS and SSH keys with production access.
- Move to managed storage: import keys into a certificate manager, KMS or secrets manager, or replace them with automated short-lived issuance, then delete the files.
- Prevent: enable pre-commit and repository rules for key extensions and labels, run them in audit mode for two weeks to tune false positives, then block.
- Roll back safely: keep the old certificate valid until the new one is confirmed in service, so a failed reissue does not cause an outage.
Storage decision guidance
| Use case | Preferred storage | Acceptable fallback |
|---|---|---|
| Public TLS on cloud load balancers | Cloud certificate manager, key never exported | Encrypted PFX imported then deleted |
| Internal service certificates | Automated issuance (ACME, SPIFFE or a secrets manager) with short lifetimes | Encrypted PKCS #8 file, readable only by the service account |
| Code signing | HSM or cloud KMS, signing through an API | Hardware token: see the USB PKI tokens and eTokens guide |
| Administrator SSH keys | Hardware-backed keys or SSH certificates | Passphrase-protected OpenSSH or PPK v3 file |
| Handing a certificate to a partner | Send only the .crt or chain .pem | Never send a PFX by email or chat |
Small teams can get most of the benefit by using their cloud provider's certificate service and a secrets manager. Large organisations should add an inventory of key files on hosts and a policy that bans exportable keys for high-value certificates. On disk, private key files should be readable only by the owning service account (for example mode 0600 on Linux), excluded from backups that leave the security boundary, and stored encrypted.
Secret scanning and detection
- Text keys: scanners such as gitleaks match
-----BEGIN ... PRIVATE KEY-----blocks, which covers PKCS #8, traditional and OpenSSH keys. Add a custom rule forPuTTY-User-Key-File-headers if your scanner lacks one. See the Secret Scanner Rule Coverage Comparison Guide. - Binary containers: PFX, P12 and JKS files are binary, so content regexes miss them. Block them by extension in pre-commit hooks and repository rules, and scan artefact stores and file shares by extension and magic bytes.
- Measure: private key files found in repositories (target 0 new per month); unencrypted key files on servers; certificates with exportable keys for high-value services; percentage of certificates issued through automation; and mean time to rotate a certificate after its key is exposed.
Common misconceptions
- "A .pem is a certificate": PEM is only an encoding. Open the file and read the labels before sharing it.
- ".cer and .crt are different formats": both are naming conventions for a certificate; the real difference is whether the content is DER or PEM.
- "A password-protected PFX is safe to share": the protection is only as strong as the password and the algorithm. Legacy RC2-40 or 3DES files with short passwords can be brute forced offline.
- "The thumbprint is a field in the certificate": it is computed by the tool, and different tools default to different hashes, so a SHA-1 and a SHA-256 fingerprint of the same certificate never match.
- "Removing the key from the repository fixes the leak": the key remains in history and in clones. Revoke and reissue the certificate, then clean history.
- "The CSR is secret": a CSR is public, but its matching private key was generated alongside it, so look for the key file wherever you find a CSR.
Related concepts
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SC-12 Cryptographic Key Establishment and Management | Key generation, storage and destruction |
| NIST SP 800-53 Rev. 5 | SC-17 Public Key Infrastructure Certificates | Issuing and managing certificates |
| NIST SP 800-53 Rev. 5 | IA-5(2) Public Key-based Authentication | Protecting private keys used for authentication |
| MITRE ATT&CK | T1552.004 Private Keys | Adversaries searching for key and certificate files |
| MITRE ATT&CK | T1649 Steal or Forge Authentication Certificates | Theft of certificates and keys for authentication |
See also the Machine Identity, PKI and Certificate Lifecycle Guide for issuance and renewal, and APK Signing for how Android signing keys are stored in keystores.
Practitioner checklist
- Identify file content by PEM label or by parsing, never by extension alone.
- Treat every PFX, P12, JKS, PPK,
.keyand OpenSSH key file as a secret. - Store standalone keys as
ENCRYPTED PRIVATE KEYor in a key manager, readable only by the owning account. - Re-export legacy PKCS #12 files with AES-256 and PBKDF2, and strong passwords.
- Record SHA-256 fingerprints alongside any SHA-1 thumbprints used for lookup.
- Delete intermediate files after conversions and never use
-noencon shared hosts. - Block key and container extensions in repositories and add scanner rules for PPK headers.
- Revoke and reissue on any key exposure; deleting the file is not remediation.
Standards and references
- IETF: RFC 7468 Textual Encodings of PKIX, PKCS, and CMS Structures
- IETF: RFC 7292 PKCS #12: Personal Information Exchange Syntax v1.1
- OpenSSL: openssl-x509 manual
- OpenSSL: openssl-pkcs12 manual
- OpenSSL: openssl-format-options manual
- PuTTY: PPK file format
- Microsoft Learn: X509Certificate2.Thumbprint
- MITRE ATT&CK: Unsecured Credentials: Private Keys
Related NHI Mgmt Group resources: Java Keystores Guide · PKI Basics Guide · Private Keys in Repositories Guide · SSH Key Management Guide