3) if I change at (A) the password to "storePassword" I can read the p12
properly using OpenSSL using "storePassword" both for "Import password"
and "PEM pass phrase" but the JUnit still fails as in 1).

I know this is BC mailing list and not OpenSSL's one, but I have
to express my frustration (:D) because:

that option has a description — "prompt for separate
integrity and encryption passwords: most software always
assumes these are the same so this option will render such
PKCS#12 files unreadable" — which seems related to the
creation of a P12 while it's listed under "PARSING OPTIONS";

I don't understand why I need to pass that option (can't
OpenSSL just prompt for passwords the same way it does without
that option?);

I have to enter keyPassword three (3!) times, while just one
time would be sufficient.

I hope this thread will help someone else :-)

Giacomo

Giacomo Boccardo wrote on 10/07/2017 23:48:

Oops, forget about the error related to point 1): when I restored JDK
policies to the default ones I made a terrible mistake :-)
So the only issue is that I can't read the P12 using OpenSSL when the
key password differs from the store password.
Is it an OpenSSL limit or I created something strange considering that
usually a P12 with a private key requires a certificate chain?
Giacomo Boccardo wrote on 10/07/2017 23:31:

Hi,
what I need is to create a PKCS#12 containing an encrypted PKCS#8
RSA private key using a store password different from the key password.
I'd prefer avoiding to alter the JDK adding policy files.
I produced the following code using a JDK8 without any additional policy
and BC 1.57 but I have some issues:
1) the code fails at (B) with an error which suggests I should add
policies to the JDK...but I created the P12 without those policies, so I
don't understand why I can't read it back...
java.lang.ExceptionInInitializerError
at javax.crypto.Mac.getInstance(Mac.java:176)
at
sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2039)
at java.security.KeyStore.load(KeyStore.java:1445)
[OMISSIS]
Caused by: java.lang.SecurityException: Can not initialize cryptographic
mechanism
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:88)
... 27 more
Caused by: java.lang.SecurityException: Cannot locate policy or
framework files!
at
javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:255)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:48)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:80)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:77)
... 27 more
2) if I try to read the p12 using OpenSSL and the import password
"storePassword" the result is
$ /usr/local/Cellar/openssl/1.0.2l/bin/openssl pkcs12 -info -in /tmp/a.p12
Enter Import Password:
MAC Iteration 1024
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Bag Attributes: <Empty Attributes>
Error outputting keys and certificates
140736555361288:error:06065064:digital envelope
routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:531:
140736555361288:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12
cipherfinal error:p12_decr.c:108:
140736555361288:error:2306A075:PKCS12
routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:139:
3) if I change at (A) the password to "storePassword" I can read the p12
properly using OpenSSL using "storePassword" both for "Import password"
and "PEM pass phrase" but the JUnit still fails as in 1).
What's wrong with this approach?
@Test
public void testPKCS12() throws Exception {
final String keyPassword = "keyPassword";
final String storePassword = "storePassword";
final KeyPairGenerator keyPairGenerator =
KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
final KeyPair keyPair = keyPairGenerator.genKeyPair();
final ByteArrayOutputStream pkcs12OS = new ByteArrayOutputStream();
// (A)
final PKCS12SafeBagBuilder keyBagBuilder = new
JcaPKCS12SafeBagBuilder(keyPair.getPrivate(),
new
BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC,
new CBCBlockCipher(new DESedeEngine())).build(keyPassword.toCharArray()));
final PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder();
pfxPduBuilder.addData(keyBagBuilder.build());
final PKCS12PfxPdu pkcs12PfxPdu = pfxPduBuilder.build(new
BcPKCS12MacCalculatorBuilder(), storePassword.toCharArray());
pkcs12OS.write(pkcs12PfxPdu.getEncoded(ASN1Encoding.DL));
pkcs12OS.close();
final byte[] pkcs12BA = pkcs12OS.toByteArray();
FileUtils.writeByteArrayToFile(new File("/tmp/a.p12"), pkcs12BA);
final KeyStore ks = KeyStore.getInstance("PKCS12");
// (B)
ks.load(new ByteArrayInputStream(pkcs12BA),
storePassword.toCharArray());
final String alias = ks.aliases().nextElement();
final RSAPrivateKey privateKey = (RSAPrivateKey)
ks.getKey(alias, keyPassword.toCharArray());
System.out.println(privateKey.getPrivateExponent());
}
Thanks in advance,
Giacomo