require "openssl" password = ENV.fetch("P12_PASSWORD")key = OpenSSL::PKey.read(File.read("key.pem"))leaf = OpenSSL::X509::Certificate.new(File.read("leaf.pem"))chain = [OpenSSL::X509::Certificate.new(File.read("intermediate.pem"))] # name is the friendly name; the protection algorithms are OpenSSL's defaults (AES-256 with OpenSSL 3)p12 = OpenSSL::PKCS12.create(password, "api.example.com", key, leaf, chain)File.binwrite("bundle.p12", p12.to_der) require "openssl" password = ENV.fetch("P12_PASSWORD")p12 = OpenSSL::PKCS12.new(File.binread("bundle.p12"), password)puts "certificate: #{p12.certificate.subject.to_s(OpenSSL::X509::Name::RFC2253)}"p12.ca_certs.to_a.each { |cert| puts "chain: #{cert.subject.to_s(OpenSSL::X509::Name::RFC2253)}" }puts "key matches certificate: #{p12.certificate.check_private_key(p12.key)}" begin OpenSSL::PKCS12.new(File.binread("bundle.p12"), "wrong-password")rescue OpenSSL::PKCS12::PKCS12Error => e puts "wrong password: #{e.message}"end How it works
OpenSSL::PKCS12.create(password, name, key, cert, ca_certs)builds the bundle;namebecomes the friendly name andca_certsis the chain without the leaf.- Without explicit algorithm arguments the library uses OpenSSL's defaults: AES-256-CBC with PBKDF2-HMAC-SHA256 and an HMAC-SHA-256 MAC on OpenSSL 3.5, as the run shows.
OpenSSL::PKCS12.new(der, password)exposeskey,certificateandca_certs;check_private_keyconfirms the pair.- Write and read the file with
File.binwrite/File.binread: it is binary DER.
Gotchas
- A wrong password raises
OpenSSL::PKCS12::PKCS12Error: PKCS12_parse: mac verify failure; rescue it explicitly. ca_certsisnil, not an empty array, when the bundle has no chain (checked in the run) — iterate overca_certs.to_a.- The protection is whatever the linked OpenSSL uses by default (AES-256 with OpenSSL 3.5 here); pass the algorithm arguments of
createwhen the output must not depend on the system Ruby runs on.
Related recipes
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain in PHP
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain with OpenSSL
- How to create a PKCS#12 (.p12/.pfx) file from a key and certificate chain in Python
- How to convert a certificate and a private key between PEM and DER in Ruby
- How to verify a certificate chain against your own trust store in Ruby