Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8231581

Add support for PBES2 encoding/decoding in javax.crypto.EncryptedPrivateKeyInfo



      Windows 8.1 x64
      java version "11.0.4" 2019-07-16 LTS
      Java(TM) SE Runtime Environment 18.9 (build 11.0.4+10-LTS)
      Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.4+10-LTS, mixed mode)


      javax.crypto.EncryptedPrivateKeyInfo only works for PBES1 algorithm names. Please add encode/decode support for PBES2 algorithm names. Encoding formats are different for PBES1 vs PBES1, and javax.crypto.EncryptedPrivateKeyInfo only implements PBES1 format.

      This limitation blocks encoding of PKCS#8 encrypted private keys. If encrypted with modern PBKDF2+HmacSHA256+AES256 then encoding does not work. If encrypted with legacy PBKDF1+SHA1+3DES the encoding works, but these algorithms are deprecated and insecure. PKCS#12 private key entries are also affected, because PKCS#12 shrouded key bags are PKCS#8 EncryptedPrivateKeyInfo ASN.1 format too.


      The SunJCE provider supports PBES1 & PBES2 algorithm names for password-based encrypt/decrypt. Examples algorithm names in Java 11 for SecretKeyFactory, Cipher, and AlgorithmParameters (https://docs.oracle.com/en/java/javase/11/security/oracle-providers.html) are:
      - PBES1 => PBEWithSHA1AndDESede
      - PBES2 => PBEWithHmacSHA256AndAES_256

      The names come from RFC 8018 (PKCS#5 v2.1) and RFC 7292 (PKCS#12).
      - PBES1: https://tools.ietf.org/html/rfc8018#section-6.1 (legacy encryption & ASN.1 format)
      - PBES2: https://tools.ietf.org/html/rfc8018#section-6.2 (modern encryption & ASN.1 format, recommended by PKCS#5, PKCS#8, and PKCS#12)
      - PBES1: https://tools.ietf.org/html/rfc7292#appendix-C (extra legacy algoritihms not defined by PKCS#5, such as the PBKDF1+SHA1+3DES combination)

      Password-based encryption works for any input bytes. For the special case of private key encryption, two outputs from Cipher API can be passed to the javax.crypto.EncryptedPrivateKeyInfo constructor. That class supports encoding of the encrypted data & parameters in PKCS#8 EncryptedPrivateKeyInfo ASN.1 format (https://tools.ietf.org/html/rfc5208#section-6).

      EncryptedPrivateKeyInfo ::= SEQUENCE {
          encryptionAlgorithm EncryptionAlgorithmIdentifier,
          encryptedData EncryptedData

      ASN.1 encoding is different for PBES1 vs PBES2. PBES1 names are encoded as different OIDs, while PBES2 names map to single OID.

      - PBES1 (https://tools.ietf.org/html/rfc8018#appendix-A.3): Unique OIDs are different combinations PBKDF1+PRF+Encrypt (i.e. PKCS#5 v1.5 legacy encryption).
      - PBES2 (https://tools.ietf.org/html/rfc8018#appendix-A.4): One OID wrap separate OIDs for the PBKDF2+PRF+Encrypt options (i.e. PKCS#5 v2.0 modern encryption).

      Example name to OID mappings:
      - PBES1: PBEWithSHA1AndDESede (pbeWithSHAAnd3-KeyTripleDES-CBC=1.2.840.113549.
      - PBES2: PBEWithHmacSHA256AndAES_256 (id-PBES2=1.2.840.113549.1.5.13), which wraps other OIDs (id-PBKDF2=1.2.840.113549.1.5.12, id-hmacWithSHA256=1.2.840.113549.2.9, aes256-CBC=2.16.840.

      Example code to reproduce this issue is in this defect for Java 8 & 11. The defect is still unresolved.
      - https://bugs.openjdk.java.net/browse/JDK-8226824

      If I run the example code with:
      - PBEWithSHA1AndDESede, encrypt works and encode works (i.e. PBES1 encode)
      - PBEWithHmacSHA256AndAES_256, encrypt works but encode fails (i.e. PBES2 encode)

      Root cause is EncryptedPrivateKeyInfo constructor calls /master/jdk/src/share/classes/sun/security/x509/AlgorithmId.java. This call attempts to map AlgorithmParameters.getName() to an OID. SunJCE provider only registers name to OID mappings for PBES1 names. None of the PBES2 name to OID mappings are registered in SunJCE.

      Please enhannce SunJCE provider to add the missing PBES2 name to OID mappings. All of the PBES2 names should map to a single OID (1.2.840.113549.1.5.13). No change is required for AlgorithmId, it will return the common PBES2 OID now. Please enhance EncryptedPrivateKeyInfo to check for the PBES2 OID. If it is PBES2, invoke new code to handle PBES2 format. If not PBES2, fall back to PBES1 format which is already implemented.




            • Assignee:
              jnimeh Jamil Nimeh
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              4 Start watching this issue


              • Created: