Skip to content

Handles and converts PKCS#12 files that are not compatible with Java#765

Merged
kaikramer merged 2 commits intokaikramer:mainfrom
jonwltn:p12-certs
Mar 8, 2026
Merged

Handles and converts PKCS#12 files that are not compatible with Java#765
kaikramer merged 2 commits intokaikramer:mainfrom
jonwltn:p12-certs

Conversation

@jonwltn
Copy link
Contributor

@jonwltn jonwltn commented Mar 6, 2026

This PR implements #760. I didn't try to refactor the P12 parsing logic. I just copied the portions needed for extracting the certs and friendly names.

This PR also fixes two defects with file reloading:

  • NullPointerException if the reloaded file exists but is no longer a supported key store file
  • Need to use a null ProtectionParameter for reading cert entries

Dialog prompts for conversion of the key store when KSE identifies that it contains certificates that are not part of any private key cert chain or with the Java trusted cert identifier:
image

Clicking "No" leaves the key store as it is, and the cert is lost if the user performs any operation that modifies the key store.
image

Clicking "Yes" converts the key store:
image

The conversion can be undone:
image

Let me know if there are any changes that you would like.

Copy link
Owner

@kaikramer kaikramer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for PR!

super.load(new ByteArrayInputStream(data), password);

Set<Certificate> visibleCerts = extractAllCertificates();
invisibleCerts = parseP12(data, password).stream() //
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invisible comments for the invisible certificates - nice :-)

return 128;
} else if (id_aes256_GCM.getId().equals(id)) {
return 256;
} else if (id_camellia128_cbc.getId().equals(id)) {
Copy link
Owner

@kaikramer kaikramer Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did you get this list of algorithms from? I was not aware that these are used for PKCS#12 encryption.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it from org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.DefaultSecretKeyProvider. It is used by BC when constructing the PBKDF2KeySpec. I went looking for uses of PBKDF2KeySpec, and that's what I found in the BC provider.

It's not documented, but OpenSSL can construct such P12 files using this command:
openssl pkcs12 -export -inkey my.key -in my.cer -out my.p12 -keypbe CAMELLIA-256-CBC -certpbe CAMELLIA-256-CBC

From DPkcs12Info:

Properties for 'camellia.p12'
    File: /Users/camellia.p12
    Type: PKCS#12
    MAC
        Algorithm: Sha-256 (2.16.840.1.101.3.4.2.1)
        Salt: 16 bytes
        Iterations: 2,048
    PKCS#7 Encrypted Data
        Algorithm: Pkcs5PBES2 (1.2.840.113549.1.5.13)
        Key Derivation Function: Pkcs5PBKDF2 (1.2.840.113549.1.5.12)
        Salt: 16 bytes
        Iterations: 2,048
        Encryption Scheme: 1.2.392.200011.61.1.1.1.4
        Certificate Bag
            Subject: CN=ML-KEM
            Issuer: CN=ML-DSA Authority
            Serial Number: 50c61c75fe94be2dab9969c4cb49019b73760f93
            Validity: Wed Dec 31 00:11:15 PST 2025 - Fri Dec 31 00:11:15 PST 2027
            Bag Attributes
                Local ID: f59c9d1207041d2cd2dc6678e94a01ba20f271bf
        Certificate Bag
            Subject: CN=ML-DSA Authority
            Issuer: CN=ML-DSA Authority
            Serial Number: 50a8a44f5dd2c8c529246e4de6a5019b737560b7
            Validity: Wed Dec 31 00:10:30 PST 2025 - Fri Dec 31 00:10:30 PST 2027
            Bag Attributes
    PKCS#7 Data
        PKCS#8 Shrouded Key Bag
            Algorithm: Pkcs5PBES2 (1.2.840.113549.1.5.13)
            Key Derivation Function: Pkcs5PBKDF2 (1.2.840.113549.1.5.12)
            PBKDF2 Salt: 16 bytes
            PBKDF2 Iterations: 2,048
            Encryption Scheme: 1.2.392.200011.61.1.1.1.4
            Bag Attributes
                Local ID: f59c9d1207041d2cd2dc6678e94a01ba20f271bf

But then the Java PKCS12 KeyStore provider chokes on it:

org.kse.crypto.keystore.KeyStoreLoadException: Could not load KeyStore as type 'PKCS12'.
	at org.kse.crypto.keystore.KeyStoreUtil.load(KeyStoreUtil.java:176)
	at org.kse.crypto.keystore.KeyStoreUtil.load(KeyStoreUtil.java:132)
<snip>
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

java.io.IOException: parseAlgParameters failed: PBE parameter parsing error: expecting the object identifier for AES cipher
	at java.base/sun.security.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:855)
	at java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2113)
	at java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:221)
	at java.base/java.security.KeyStore.load(KeyStore.java:1473)
<snip>
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

So it really isn't necessary to add those other ciphers. The Java provider does not support them.

@kaikramer kaikramer merged commit 81a33f5 into kaikramer:main Mar 8, 2026
4 checks passed
@jonwltn jonwltn deleted the p12-certs branch March 9, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants