RFR: 8360564: Implement JEP 524: PEM Encodings of Cryptographic Objects (Second Preview) [v4]
Sean Mullan
mullan at openjdk.org
Fri Oct 3 20:31:58 UTC 2025
On Thu, 25 Sep 2025 23:03:11 GMT, Anthony Scarpino <ascarpino at openjdk.org> wrote:
>> Hi
>>
>> Please review the [Second Preview](https://openjdk.org/jeps/8360563) for the PEM API. The most significant changes from [JEP 470](https://openjdk.org/jeps/470) are:
>>
>> - Renamed the name of `PEMRecord` class to `PEM`.
>> - Revised the new `encryptKey` methods of the `EncryptedPrivateKeyInfo` class to accept `DEREncodable` objects rather than just `PrivateKey` objects so that cryptographic objects with public keys, i.e., `KeyPair` and `PKCS8EncodedKeySpec`, can also be encrypted.
>> - Enhanced the `PEMEncoder` and `PEMDecoder` classes to support the encryption and decryption of `KeyPair` and `PKCS8EncodedKeySpec` objects.
>>
>> thanks
>>
>> Tony
>
> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision:
>
> missed some decoder comments
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 393:
> 391:
> 392: /**
> 393: * Creates and encrypts an {@code EncryptedPrivateKeyInfo} from a given
s/a given/the specified/
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 394:
> 392: /**
> 393: * Creates and encrypts an {@code EncryptedPrivateKeyInfo} from a given
> 394: * {@code DEREncodable} and password. Default algorithm and parameters are
Need to be more specific - what algorithm and what parameters.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 398:
> 396: *
> 397: * @param de the {@code DEREncodable} to be encrypted. Usage
> 398: * limited to {@link PrivateKey}, {@link KeyPair}, and
"Usage limited" sounds odd. Maybe "The supported `DEREncodable types are ... An IllegalArgumentException is thrown for any other type."
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 402:
> 400: * @param password the password used in the PBE encryption. This array
> 401: * will be cloned before being used.
> 402: * @return an {@code EncryptedPrivateKeyInfo}
Next line:
"@throws IllegalArgumentException on initialization errors based on the
arguments passed to the method"
What does this mean - you need to be more specific about what are the error cases. Otherwise it will not be helpful for TCK test writers on how to test this.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 413:
> 411: * {@code AlgorithmParameterSpec} are the provider's algorithm defaults.
> 412: *
> 413: * @since 25
Throwing a RuntimeException on encryption error is too general.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 535:
> 533: * @param decryptKey the decryption key and cannot be {@code null}
> 534: * @param provider the {@code Provider} used for Cipher decryption and
> 535: * {@code PrivateKey} generation. A {@code null} value will
Same comment about provider as below.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 540:
> 538: * @throws GeneralSecurityException if an error occurs parsing,
> 539: * decrypting the data, or producing the key object.
> 540: * @throws NullPointerException if {@code decryptKey} is {@code null}
Same comment about exceptions as below.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 565:
> 563: */
> 564: @PreviewFeature(feature = PreviewFeature.Feature.PEM_API)
> 565: public KeyPair getKeyPair(char[] password) throws GeneralSecurityException {
This should specifically throw an `InvalidKeyException` if decryption fails. I think you want to specify the exact subclasses when it is clearly the right behavior. In this case, the method should always throw `InvalidKeyException` on decryption errors.
Also why generalize it to throw `GeneralSecurityException`? This should throw the same exceptions as `getKeySpec(Key, Provider)` since the params are the same.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 585:
> 583: * @param decryptKey the decryption key and cannot be {@code null}
> 584: * @param provider the {@code Provider} used for Cipher decryption and
> 585: * key generation. A {@code null} value will
Why do you allow null? This is inconsistent with the other methods that take Provider arguments. I think consistency is important.
src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java line 588:
> 586: * use the default provider configuration.
> 587: * @return a {@code KeyPair} extracted from the encrypted data
> 588: * @throws GeneralSecurityException if an error occurs parsing,
Same comment as above on the exceptions.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403250173
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403251624
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403255532
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403260574
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403264388
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403246374
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403245654
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403237211
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403243416
PR Review Comment: https://git.openjdk.org/jdk/pull/27147#discussion_r2403241992
More information about the security-dev
mailing list