Skip to content
Advertisement

Loading pkcs12 file with BouncyCastle fails on unknown PRF algorithm (hmacWithSHA256)

we have a certificate in a pkcs#12 format provided by a 3rd party (not managed by us). We must sign emails with this certificate before sending them to this specific customer from our platform.

There were no issues with the old certificate, but as it is about to expire we need to replace it by a newer one, which has following key encryption schema (extracted via openssl):

PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256

When trying to load this keystore with bouncycastle security provider we get a following error

Caused by: java.io.IOException: exception unwrapping private key - java.security.spec.InvalidKeySpecException: Invalid KeySpec: unknown PRF algorithm 1.2.840.113549.2.9
    at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(Unknown Source)
    at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source)
    at java.security.KeyStore.load(KeyStore.java:1445)
    at org.obfuscated.SignEmailGenerator.loadKeyStore(SignEmailGenerator.java:130)

code (exception handling and other utility code removed for brevity):

KeyStore keystore = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);        
InputStream trustStoreInputStream = MethodHandles.lookup().lookupClass()
                .getResourceAsStream(mailSigningConfiguration.getKeyStorePath());
keystore.load(trustStoreInputStream, mailSigningConfiguration.getKeyStorePassword().toCharArray());

The 1.2.840.113549.2.9 is an OID for hmacWithSHA256 which leads me to the question. Does bouncy castle not support this algorithm? Based on http://www.bouncycastle.org/specifications.html I would guess it should? If it does support it, why am I unable to load such file?

Jdk 1.8.0 bcmail-jdk15on version 1.66

Any input is appreciated, thank you.

Edit (private key is part of the file):

c:ProgramyOpenSSL-Win64bin>openssl pkcs12 -info -in PrivateKey.pfx -nodes -nocerts
Enter Import Password:
MAC: sha256, Iteration 2000
MAC length: 32, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256
Bag Attributes
    localKeyID: 01 00 00 00
    friendlyName: ---ommited---
    Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
Key Attributes
    X509v3 Key Usage: 10
-----BEGIN PRIVATE KEY-----
-- data is here, but I've ommited it ---
-----END PRIVATE KEY-----
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256
Certificate bag
Certificate bag
Certificate bag

Answer

Encounter this problem today, the BouncyCastle provider in use is 1.51. Exception in server log is:

2022-01-13 14:28:28,699 ERROR (default task-46) getKeyStore,load. location:xxx.p12 at xxx: java.io.IOException: exception unwrapping private key - java.security.spec.InvalidKeySpecException: Invalid KeySpec: unknown PRF algorithm 1.2.840.113549.2.9
    at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.unwrapKey(Unknown Source)
    at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source)
    at java.security.KeyStore.load(KeyStore.java:1445)

After checked the p12 with openssl.

$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
Enter Import Password:
MAC: sha1, Iteration 100000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Bag Attributes

I tested it in another environment with BouncyCastle provider 1.69, worked fine. But due to the provider cannot be upgraded on server, I had to re-created the p12 keystore via openssl to align the encryption with some old keystores in server, then it worked.

openssl pkcs12 -export -inkey <private> -in <cert> -name <alias> -out <keystore>.p12

Check the re-created keystore info:

$> openssl pkcs12 -info -in xxx.p12 -nodes -nocerts
Enter Import Password:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Advertisement