# Key + certificate + chain into one password-protected file (AES-256 with OpenSSL 3)openssl pkcs12 -export -inkey key.pem -in leaf.pem -certfile intermediate.pem \ -name "api.example.com" -passout env:P12_PASSWORD -out bundle.p12# Back to PEM: the key (unencrypted with -nodes) and every certificateopenssl pkcs12 -in bundle.p12 -passin env:P12_PASSWORD -nodes -out everything.pemgrep -E '^-----BEGIN' everything.pem# Only the certificates, or only the keyopenssl pkcs12 -in bundle.p12 -passin env:P12_PASSWORD -nokeys -out chain.pemopenssl pkcs12 -in bundle.p12 -passin env:P12_PASSWORD -nocerts -nodes -out bundle-key.pem# Files from older tools use RC2/3DES, which OpenSSL 3 only reads with -legacyopenssl pkcs12 -in old.p12 -passin env:P12_PASSWORD -legacy -nodes -out old.pem # ...and the same switch writes such a file for software that cannot read AESopenssl pkcs12 -export -legacy -inkey key.pem -in leaf.pem -certfile intermediate.pem \ -name "api.example.com" -passout env:P12_PASSWORD -out old.p12How it works
-inkeyis the private key,-inthe certificate it belongs to,-certfilethe chain (intermediates, optionally the root);-namesets the friendly name that keystores show as the alias.-passout env:P12_PASSWORDreads the password from an environment variable, so it never appears in the command line or the shell history;-passindoes the same for reading.- OpenSSL 3 protects the bundle with PBES2 — PBKDF2 with HMAC-SHA-256 and AES-256-CBC — for both the key and the certificates, plus an HMAC-SHA-256 MAC over the whole file, 2048 iterations each.
- Reading with
-nodeswrites the key unencrypted;-nokeysand-nocertsselect one part. The run checks that the key in the bundle belongs toleaf.pemand that a wrong password fails withMac verify error: invalid password?.
Gotchas
- Files from OpenSSL 1.x, older Java and Windows use 40-bit RC2 or 3DES. OpenSSL 3 refuses to read them without
-legacy— the error names the algorithm:unsupported … Algorithm (RC2-40-CBC : 0). Add-legacy; it needs the legacy provider, which Debian ships with OpenSSL. -legacyalso writes such files (40-bit RC2 for the certificates in the run) for readers that only know the old algorithms. Prefer upgrading the reader: RC2-40 offers no real protection.-nodes("no DES") writes the private key without a password. Keep the output out of version control and set its permissions as tight as the bundle's.-certfileis how the chain gets in: without it the bundle holds only the leaf, and servers that load it send an incomplete chain.
Related recipes
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain in Python
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain in Java
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain in C# (.NET)
- How to convert a certificate and a private key between PEM and DER with OpenSSL
- How to verify a certificate chain against your own trust store with OpenSSL