pkcs12_parser 1.1.0
pkcs12_parser: ^1.1.0 copied to clipboard
Pure-Dart PKCS#12 (.pfx/.p12) parser. Extracts certificates, private and public keys without OpenSSL. Supports PBES1, PBES2 (AES), MAC verification, RSA and EC.
pkcs12_parser #
Pure-Dart PKCS#12 (.pfx / .p12) parser — extracts the certificate, private
key and public key from a password-protected container without OpenSSL or
FFI. Works in any Dart or Flutter environment (mobile, desktop, server).
The only dependency is pointycastle.
Usage #
import 'dart:io';
import 'package:pkcs12_parser/pkcs12_parser.dart';
void main() {
final bytes = File('my.pfx').readAsBytesSync();
final pfx = Pkcs12.load(bytes, 'password');
final cert = pfx.certificate; // X509CertificateDer (raw DER + PEM)
print(cert.notAfter); // validity end, UTC (also notBefore, isValidAt)
print(cert.subject['CN']); // subject attributes (also issuer, serialNumber)
final privateKey = pfx.privateKey; // RSAPrivateKey or ECPrivateKey
final publicKey = pfx.publicKey; // RSAPublicKey or ECPublicKey
print(pfx.privateKeyPem); // -----BEGIN PRIVATE KEY----- (PKCS#8)
print(pfx.certificatePem); // -----BEGIN CERTIFICATE-----
print(pfx.caChainPem); // CA chain, issuer-ordered
}
The key objects are plain pointycastle types (re-exported by this package), ready for signing/decryption:
switch (pfx.privateKey) {
case RSAPrivateKey key:
print('RSA, ${key.modulus!.bitLength} bits');
case ECPrivateKey key:
print('EC on ${key.parameters!.domainName}');
}
Certificate details #
X509CertificateDer (pfx.certificate, and the entries of the CA chain) reads
the few X.509 fields most applications need, without a full X.509 model:
final cert = Pkcs12.load(bytes, 'password').certificate;
cert.notBefore; // DateTime (UTC)
cert.notAfter; // DateTime (UTC)
cert.isValidAt(); // inside the validity period right now?
cert.subject['CN']; // 'FISKAL 4'
cert.subject['O']; // 'FRAKTAL D.O.O.'
cert.subject['2.5.4.97']; // attributes without a short name use the OID
cert.issuer['CN'];
cert.serialNumber; // upper-case hex, like `openssl x509 -serial`
Short names: CN, O, OU, C, L, ST, SERIALNUMBER.
Supported formats #
- Legacy PBES1 (Windows exports, OpenSSL ≤ 1.x,
openssl pkcs12 -legacy): pbeWithSHA1And3-KeyTripleDES-CBC, 2-KeyTripleDES, RC2-40/128, RC4-40/128, using the RFC 7292 appendix B KDF with BMPString passwords. - Modern PBES2 (OpenSSL 3.x default): PBKDF2 (hmacWithSHA1/256/384/512) with AES-128/192/256-CBC or des-EDE3-CBC.
- MAC verification: HMAC-SHA1/SHA256/SHA384/SHA512 over the authenticated
safe, on by default (
verifyMac: falseto skip).nulland''passwords are distinct encodings; both are tried automatically, as OpenSSL does. - Keys: RSA (PKCS#1) and EC (RFC 5915 — P-256/384/521, secp256k1,
brainpool). Key ↔ certificate pairing via
localKeyId, falling back to public-key comparison.
Error handling #
All failures throw a subtype of Pkcs12Exception:
| Exception | Meaning |
|---|---|
Pkcs12MacMismatchException |
Wrong password, or tampered/corrupted file |
Pkcs12BadPasswordException |
Decryption padding failure (wrong password when the MAC is skipped or absent) |
Pkcs12UnsupportedException |
Algorithm this parser does not implement (message names the OID) |
Pkcs12ParseException |
Malformed ASN.1 / not a PKCS#12 file |
CLI #
dart run pkcs12_parser <file.p12> [password] # prints key + certs as PEM
Tests #
dart test
Fixtures in test/fixtures/ were generated once with OpenSSL 3.x (see
test/fixtures/README.md); OpenSSL is not needed to run the tests or use
the package.