Search code examples
javamacosbouncycastlekeystore

Import Java created .p12 into macos keychain fails with invalid password


I have a Java application which creates .p12 files (with Bouncycastle (BC)). I'm not able to import the .p12 file created via Java into macOS (macos 11) keychain:

security import mycert-personauth.p12 -k ~/Library/Keychains/login.keychain-db

This prompts for the password and when I enter it fails "Sorry, you entered an invalid password". If I use the same password with openssl to view the file it works fine:

openssl pkcs12 -in mycert-personauth.p12 -info  -nokeys -passin pass:$pw

If I create a p12 from the same certs in mycert-personauth.p12 it works.

openssl pkcs12 -export -out ~/test1.pfx -inkey cert/mytest-personauth.key -in cert/mytest-personauth.crt -certfile ca/ca-trust.crt
security import ~/test1.pfx -k ~/Library/Keychains/login.keychain-db 
[ GUI prompt for password here ]
1 identity imported.
2 certificates imported.

Here is the non-working myc ert-personauth.p12 as reported by openssl (run on Linux with openssl 3.0.11):

MAC: sha256, Iteration 10000
MAC length: 32, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Certificate bag
Bag Attributes
friendlyName: certandkey
localKeyID: 54 69 6D 65 20 31 37 31 37 37 31 30 30 32 33 39 38 31
subject=/DC=com/DC=contoso/CN=Users/CN=David Bowie
issuer=/DC=com/DC=contoso/CN=Contoso Issuing CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Certificate bag
Bag Attributes
    friendlyName: CN=Contoso Issuing CA,DC=contoso,DC=com
subject=/DC=com/DC=contoso/CN=Contoso Issuing CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Certificate bag
Bag Attributes
    friendlyName: CN=Contoso Root CA
subject=/CN=Contoso Root CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Here is the working test1.p12 that imports successfully (openssl run on macos):

MAC Iteration 2048
MAC verified OK

PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048

Certificate bag
Bag Attributes
    localKeyID: F8 AB 55 96 23 95 4F 41 50 87 DB 98 41 DE 3A 78 50 66 2B 6D 
subject=/DC=com/DC=contoso/CN=Users/CN=David Bowie
issuer=/DC=com/DC=contoso/CN=Contoso Issuing CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Certificate bag
Bag Attributes: <No Attributes>
subject=/DC=com/DC=contoso/CN=Contoso Issuing CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Certificate bag
Bag Attributes: <No Attributes>
subject=/CN=Contoso Root CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048 

So there must be some problem in our Java code. Here is the greatly simplified Java code:

// keyPassword is set to same value as the keystore password
public void setPrivateKey(PrivateKey key, String alias, String keyPassword, java.security.cert.Certificate[] chain) {
   ...
   KeyStore keyStore = KeyStore.getInstance("PKCS12");
   // chain[0] is subject cert and chain[0-N] is ca trust
   keyStore.setKeyEntry(alias, key, keyPassword.toCharArray(), chain);
   }

EDIT 1

Copied certs to linux with openssl 3.0.11. Updated output above for mytest-personauth.p12, but test1.pfx fails to be handled by openssl on linux (works on macos openssl):

$ openssl pkcs12 -in test1.pfx -info -nokeys -passin pass:'test'
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Error outputting keys and certificates
100000000A000000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:373:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

Solution

  • Figured out the problem. I was using:

    KeyStore.getInstance("PKCS12")
    

    which creates a KeyStore using the builtin Java provider. If I use the BC provider everything works fine:

    KeyStore.getInstance("PKCS12", "BC")

    Simple solution which should have been more obvious. :(