Adobe Acrobat Reader can't open PKCS#12 file with correct password
Question:
I’m using the cryptography library to generate certificates, but I’m having trouble with it, so let me explain the steps I take. The problem is that the final PKCS#12 file can’t be imported to Adobe Acrobat Reader even though I enter the correct password. These are the steps:
- Create a private key with a given password
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
key_bytes = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.BestAvailableEncryption(
password.encode('utf-8')
)
)
# save the private key to a file
- Create a Certificate Signing Request with some properties:
csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, 'NL'),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'AAA'),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'BBB'),
x509.NameAttribute(NameOID.COMMON_NAME, 'CCC'),
x509.NameAttribute(NameOID.EMAIL_ADDRESS, 'DDD')
])).sign(key, hashes.SHA256())
csr_bytes = csr.public_bytes(serialization.Encoding.PEM)
# save the crt to a file
-
Use XCA to create a certificate. I import the request, then select "Digital Signature" as Key Usage, and "Object Signing" under Netscape. Right after that, the csr is signed, and I export the generated certificate to a file.
-
Load the private key from the file with
key = serialization.load_pem_private_key(
data, # file data
password.encode('utf-8')
)
- Load the certificate from the file with
certificate = x509.load_pem_x509_certificate(data) # certificate data
- Generate the PKCS#12 with
user_certificate_bytes = pkcs12.serialize_key_and_certificates(
name=None,
key=key,
cert=certificate,
cas=None,
encryption_algorithm=serialization.BestAvailableEncryption(
password.encode('utf-8')
)
)
and export it to a file.
- Open the PKCS#12 file in Adobe Acrobat Reader via Edit > Preferences > Signatures > Identity & trusted certificates. However, when I now want to import my certificate and filling in the correct password, it says it can’t import the certificate, even though the password is 100% correct.
To be clear, when I generate the PKCS#12 file with OpenSSL with openssl pkcs12 -export -out XXX.pfx -inkey <private key file> -in <certificate file>
, the import goes without any problem.
I’m not sure where my mistake is, hope you can help!
EDIT: Also, when dumping the contents of this generated certificate file and a correct one I had laying around, it seems cryptography is using pbeWithSHA1And3-KeyTripleDES-CBC
as the serialization (?) algorithm, while the correct one had pbeWithSHA1And40BitRC2-CBC
. Could that be a difference?
Answers:
I fixed it by using
encryption = (
PrivateFormat.PKCS12.encryption_builder().
kdf_rounds(50000).
key_cert_algorithm(pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC).
hmac_hash(hashes.SHA1()).build(b"my password")
)
as suggested in the docs as the encryption algorithm when serializing the private key and certificate. I probably should update my PDF to allow better and newer encryption methods 🙂
I’m using the cryptography library to generate certificates, but I’m having trouble with it, so let me explain the steps I take. The problem is that the final PKCS#12 file can’t be imported to Adobe Acrobat Reader even though I enter the correct password. These are the steps:
- Create a private key with a given password
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
key_bytes = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.BestAvailableEncryption(
password.encode('utf-8')
)
)
# save the private key to a file
- Create a Certificate Signing Request with some properties:
csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, 'NL'),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'AAA'),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'BBB'),
x509.NameAttribute(NameOID.COMMON_NAME, 'CCC'),
x509.NameAttribute(NameOID.EMAIL_ADDRESS, 'DDD')
])).sign(key, hashes.SHA256())
csr_bytes = csr.public_bytes(serialization.Encoding.PEM)
# save the crt to a file
-
Use XCA to create a certificate. I import the request, then select "Digital Signature" as Key Usage, and "Object Signing" under Netscape. Right after that, the csr is signed, and I export the generated certificate to a file.
-
Load the private key from the file with
key = serialization.load_pem_private_key(
data, # file data
password.encode('utf-8')
)
- Load the certificate from the file with
certificate = x509.load_pem_x509_certificate(data) # certificate data
- Generate the PKCS#12 with
user_certificate_bytes = pkcs12.serialize_key_and_certificates(
name=None,
key=key,
cert=certificate,
cas=None,
encryption_algorithm=serialization.BestAvailableEncryption(
password.encode('utf-8')
)
)
and export it to a file.
- Open the PKCS#12 file in Adobe Acrobat Reader via Edit > Preferences > Signatures > Identity & trusted certificates. However, when I now want to import my certificate and filling in the correct password, it says it can’t import the certificate, even though the password is 100% correct.
To be clear, when I generate the PKCS#12 file with OpenSSL with openssl pkcs12 -export -out XXX.pfx -inkey <private key file> -in <certificate file>
, the import goes without any problem.
I’m not sure where my mistake is, hope you can help!
EDIT: Also, when dumping the contents of this generated certificate file and a correct one I had laying around, it seems cryptography is using pbeWithSHA1And3-KeyTripleDES-CBC
as the serialization (?) algorithm, while the correct one had pbeWithSHA1And40BitRC2-CBC
. Could that be a difference?
I fixed it by using
encryption = (
PrivateFormat.PKCS12.encryption_builder().
kdf_rounds(50000).
key_cert_algorithm(pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC).
hmac_hash(hashes.SHA1()).build(b"my password")
)
as suggested in the docs as the encryption algorithm when serializing the private key and certificate. I probably should update my PDF to allow better and newer encryption methods 🙂