PKCS12(3pm)
π NAME π
Wassup bestie, you've landed on PKCS12(3pm), straight outta the User Contributed Perl Documentation β¨ and the star of this whole page is Crypt::OpenSSL::PKCS12 β a Perl extension to OpenSSL's PKCS12 API. That's it. That's the name. π
π¦ SYNOPSIS π¦
Here's the whole vibe at a glance, no cap:
use Crypt::OpenSSL::PKCS12;
my $pass = "your password";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('cert.p12');
print $pkcs12->certificate($pass);
print $pkcs12->private_key($pass);
if ($pkcs12->mac_ok($pass)) {
# MAC verification passed
}
# Creating a file
$pkcs12->create('test-cert.pem', 'test-key.pem', $pass, 'out.p12', 'friendly name');
# Creating a string
my $pkcs12_data = $pkcs12->create_as_string('test-cert.pem', 'test-key.pem', $pass, 'friendly name');
# Reproducing OpenSSL's info
my $info = $pkcs12->info($pass);
# Accessing OpenSSL's info as a hash
my $info_hash = $pkcs12->info_as_hash($pass);
πΈ VERSION πΈ
This documentation describes version 1.99 of Crypt::OpenSSL::PKCS12. Like, one point nine nine. That's the number, respect it. π
π DESCRIPTION π
Okay so here's the lore: PKCS12 is a file format for storing cryptography objects as a single file or string. One file. Everything. Iconic behaviour honestly.
PKCS12 is commonly used to bundle a private key together with its X.509 certificate, or to bundle all the members of a chain of trust. It's giving "one bag, all my little treasures" π
This distribution implements a subset of OpenSSL's PKCS12 API β not the whole thing, just a subset. Don't come for her about what's missing, mmkay?
π SUBROUTINES/METHODS π
Buckle up, this is the main character list π«Ά
new( )β Creates an emptyCrypt::OpenSSL::PKCS12object. That's all it does! If you actually want to load an existing PKCS12 structure, you usenew_from_string()ornew_from_file(). Empty object is just the starting line, bestie.legacy_support( )β Returns true if the legacy provider got successfully loaded by a prior constructor call (new_from_string()ornew_from_file()).- On OpenSSL 1.x β always returns true (the whole legacy provider concept doesn't apply there).
- On OpenSSL 3.x β returns true only if the legacy provider was loaded during the most recent constructor call.
Heads up: calling legacy_support() before you've constructed an object may return false, even if the provider is totally loadable. It's a timing thing, not a you thing. π
new_from_string( $string )new_from_file( $filename )
These two make a new Crypt::OpenSSL::PKCS12 instance β from a binary PKCS12 string or from a file path, respectively. Both forms croak on error, so like, invalid format? unreadable file? OpenSSL parse failure? Croak, croak, croak. π
Important: the binary string you pass to new_from_string() must not carry Perl's UTF-8 flag. If it does, use Encode::encode('octets', $str) to fix it up. Do not skip this. π
certificate( [$pass] )β Returns the end-entity certificate as a PEM-encoded string (that's Base64 with those-----BEGIN CERTIFICATE-----/-----END CERTIFICATE-----headers you've definitely seen before).$passis required when the PKCS12 file is password-protected. If the password is wrong, or there's simply no client certificate present, you get an empty string back. Not an error, just... empty. πΈca_certificate( [$pass] )β Returns any CA certificates in the chain as one concatenated PEM string (so multiple certs, one long string, like a group chat merged π). Empty string if there are no CA certificates at all.$passis required when the PKCS12 file is password-protected.private_key( [$pass] )β Returns the private key as a PEM-encoded string.$passis required when the PKCS12 file is password-protected. Returns an empty string if no private key is present, or if decryption fails β which, yeah, means the password was wrong. πas_string( )β Returns the PKCS12 structure as a raw binary DER string. Perfect for writing to a file or yeeting it over a network without ever touching the filesystem. The in-memory structure gets serialized as-is, so no password is needed or accepted here. She doesn't want it. Don't offer. πmac_ok( [$pass] )β Verifies the Message Authentication Code (MAC) of the PKCS12 structure using$pass. Returns true if the MAC is valid. And if it isn't? Croaks. Wrong password, corrupted file, OpenSSL error β all croaks. πchangepass( $old, $new )β Re-encrypts the PKCS12 structure with a new password.$oldis the current password,$newis the replacement. Returns false on failure.
β οΈ Big scary caveat time, bestie, read it: Changing the PKCS12 password is not supported on OpenSSL 3.x or 4.x for PBES2-encrypted files β and PBES2 is exactly what OpenSSL uses by default for newly created PKCS12 files. Sochangepass()will just return false. This is a known upstream OpenSSL limitation (openssl/openssl#19092,https://github.com/openssl/openssl/issues/19092) β not something specific to this module. Only OpenSSL 1.x is confirmed to work. Seehttps://github.com/dsully/perl-crypt-openssl-pkcs12/issues/62for the details. Your move? Consider re-creating the whole PKCS12 structure withcreate()instead. π«
create( $cert, $key, $pass, $output_file, $friendly_name )β Creates a brand new PKCS12 file at$output_fileπ$certand$keycan each be either a PEM string (detected by a-----prefix) or a filesystem path β it checks for that prefix, cute.$passis used to encrypt the private key.$friendly_nameis optional and sets the"friendlyName"bag attribute. Croaks on any OpenSSL error, obviously.create_as_string( $cert, $key, $pass, $friendly_name )β Same energy ascreate()but instead of writing to a file it returns the PKCS12 structure as a raw binary DER string.$certand$keymay each be a PEM string or a filesystem path.$friendly_nameis optional. Croaks on any OpenSSL error.info( $pass )β Returns a string containing the info about the pkcs12 file, in the exact same format theopensslcommand produces:
openssl pkcs12 -in certs/test_le_1.1.p12 -info -nodes
info_as_hash( $pass )β Same info, but as a hash: the information about the pkcs12 file, the certificates and the keys, all nestled in a data structure. π§
The format of the hash is complex, because it has to represent all the data in the PKCS12 file:
Essentially, the hash follows the format of the -info output.
pkcs7_dataandpkcs7_encrypted_dataare arrays, because more than one of each can existmacprovides the top level mac parameters for the filesafe_contents_bagis an array that contains an array of bagsbagsis an array of bags- a bag is a container for a key or certificate
Each bag has a type, and the following types are available:
key_bagcertificate_bagshrouded_keybagsecret_bagsafe_contents_bag
{
mac {
digest "sha1",
iteration 2048,
length 20,
salt_length 20
},
pkcs7_data [
[0] {
bags [
[0] {
bag_attributes {
friendlyName "...",
localKeyID "54"
},
key "...",
key_attributes {
"X509v3 Key Usage" 10
},
parameters {
iteration 10000,
nid_long_name "PBKDF2",
nid_short_name "PBKDF2"
},
type "shrouded_keybag"
}
]
},
[1] {
safe_contents_bag [
[0] {
bags [
[0] {
bag_attributes {
localKeyID "01"
friendlyName "",
},
cert "...".
issuer "...",
subject "...",
type
"certificate_bag"
}
],
type "safe_contents_bag"
}
]
}
},
[2] {
bags [
[0] {
bag_attributes {
localKeyID "02"
},
cert "...",
issuer "...",
subject "...",
type "certificate_bag"
}
]
}
],
pkcs7_encrypted_data [
[0] {
bags [
[0] {
bag_attributes {
2.16.840.1.113894.746875.1.1
"<Unsupported tag 6>",
friendlyName "..."
},
cert "...",
issuer "...",
subject "...",
type "certificate_bag"
},
[1] {
bag_attributes {
friendlyName "...",
localKeyID "54"
},
cert "...",
issuer "...",
subject "...",
type "certificate_bag"
}
],
parameters {
iteration 10000,
nid_long_name "PBKDF2",
nid_short_name "PBKDF2"
}
}
] }
And one last thing β attributes like "localKeyID" are stored as plain hex strings (e.g. "54", "01"). Always treat these values as strings in your code. Always. π
π psst β this was only part 1 of 2, so don't you dare close the tab yet.
π EXPORTS π
Okay so by default? None. Nada. Zero. The module keeps its goodies to itself until you ask π
But if you slide into the export list and request them:
NOKEYSβ bestie this is the "shhh π€«" flag: it suppresses output of private keys. No keys in your output, periodt.NOCERTSβ same energy but for certs: suppresses output of certificates. Bye felicia πINFOβ turns on structural info output. Heads up tho: this one is used internally byinfo()andinfo_as_hash(), and the output comes back as a string or a hash β it does not get printed. So don't sit there waiting for text on your screen πCLCERTSβ only client (end-entity) certificates make the cut. Very main-character-only vibe β¨CACERTSβ and this one is the opposite: only CA certificates, pls π
And icymi, these flags are literally mirror twins of the matching -nokeys, -nocerts, -info, -clcerts, and -cacerts options on the openssl pkcs12 command. Same flags, same job, just here in Perl-land π¦
π¨ DIAGNOSTICS π¨
When things go sideways, here's what you'll see:
OpenSSL error: ...β an OpenSSL call flopped π. That trailing message gets pulled fromERR_reason_error_string()and it tells you exactly which failure it was (for example,bad decryptwhen the password is wrong β we've all been there).Error opening ...βcreate()couldn't open the output file path you gave it for writing. Check that path bestie, fr fr π«Ά
βοΈ CONFIGURATION AND ENVIRONMENT βοΈ
Genuinely nothing here. No special environment needed, no config file, no secret handshake. It just works π
π¦ DEPENDENCIES π¦
This distribution needs a lil support system, and that's:
- An installation of OpenSSL, either version
1.X.Xor version3.X.X - Perl
5.14
That's the whole list, no cap π
π SEE ALSO π
The required reading / friends-of-the-show list:
OpenSSL(1)(HTTP version with OpenSSL.org:https://www.openssl.org/docs/manmaster/man1/openssl.html)Crypt::OpenSSL::X509(https://metacpan.org/pod/Crypt::OpenSSL::X509)Crypt::OpenSSL::RSA(https://metacpan.org/pod/Crypt::OpenSSL::RSA)Crypt::OpenSSL::Bignum(https://metacpan.org/pod/Crypt::OpenSSL::Bignum)- OpenSSL.org (
https://www.openssl.org/) - Wikipedia: OpenSSL (
https://en.wikipedia.org/wiki/OpenSSL) - Wikipedia: PKCS12 (
https://en.wikipedia.org/wiki/PKCS_12) - RFC:7292: "PKCS #12: Personal Information Exchange Syntax v1.1" (
https://datatracker.ietf.org/doc/html/rfc7292)
π INCOMPATIBILITIES π
So rn the library has been updated to support both OpenSSL 1.X.X and OpenSSL 3.X.X. That's it, that's the incompatibility section π«‘
π BUGS AND LIMITATIONS π
Got a known issue? Peep the GitHub repository for all the tea: https://github.com/dsully/perl-crypt-openssl-pkcs12/issues
π AUTHOR π
- Dan Sully,
<daniel@cpan.org>
Current maintainer π
- jonasbn
π«Ά CONTRIBUTORS π«Ά
In alphabetical order β contributors, bug reporters and all. Y'all ate, genuinely π
@mmuehlenhoff@sectokia@SmartCodeMaker- Alexandr Ciornii,
@chorny - Christopher Hoskin,
@mans0954 - Daisuke Murase,
@typester - Darko Prelec,
@dprelec - David Steinbrunner,
@dsteinbrunner - Gianni Ceccarelli,
@dakkar - Giuseppe Di Terlizzi,
@giterlizzi - H.Merijn Brand,
@tux - Hakim,
@osfameron - J. Nick Koston,
@bdraco - James Rouzier,
@jrouzierinverse - jonasbn.
@jonasbn - Kelson,
@kelson42 - Lance Wicks,
@lancew - Leonid Antonenkov
- Masayuki Matsuki,
@songmu - MikoΕaj Zalewski
- Shoichi Kaji
- Slaven ReziΔ
- Timothy Legge,
@timlegge - Todd Rinaldo,
@toddr
π LICENSE AND COPYRIGHT π
Copyright 2004 by Dan Sully
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.
aaaand that's the whole page bestie π this one's from perl v5.42.3, dated 2026-08-28, and it lives under the name PKCS12(3pm). go forth and un-pkcs12 responsibly, mwah πβ¨
π¦ where this page comes from
- ubuntu stonking: libcrypt-openssl-pkcs12-perl 1.99-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms