JDK-8282995 : Use larger default key sizes and algorithms based on CNSA
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.crypto
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 19
  • Submitted: 2022-03-11
  • Updated: 2022-03-23
  • Resolved: 2022-03-23
Related Reports
CSR :  
Description
Summary
-------
Increase the default key size and algorithms for various JDK security providers and tools to match the specified values in "The Commercial National Security Algorithm Suite (CNSA)" as well as the security strength in "NIST SP 800-57 Part 1-Rev.5" from National Security Agency (NSA).


Problem
-------
With increases in computing power and advances in cryptography, the recommended minimum key size and algorithms change over time. As a replacement of "Suite B Cryptography Algorithms", National Security Agency (NSA) published "The Commercial National Security Algorithm Suite (CNSA)" which specifies RSA with minimum 3072-bit key size, DH with minimum 3072-bit key size, SHA-384 as message digest algorithm, ECDH / ECDSA with P-384 curve, and AES with 256-bit key size. It's been a few years since JDK adjusted the default key sizes and algorithms. The current default key size is based on support for NSA Suite B in [JEP 129](https://openjdk.java.net/jeps/129) and less than what CNSA specifies. Signature algorithms are selected based on matching the security strength in "NIST SP 800-57 Part 1-Rev.5".

Solution
--------
Increase the default key size used by various JDK providers such as "SunRsaSign", "SunJCE", "SunEC" and "SunPKCS11" providers accordingly - increase default RSA key size from 2048 to 3072, default DH key size from 2048 to 3072, default EC key size from 256 to 384, and default AES key size to 256 if permitted by crypto policy. For keytool and jarsigner, if users do not specify key size or signature algorithm, these new default key sizes and SHA-384 message digest will be used for signature algorithms.

Specification
-------------

1) for "jdk.security.JarSigner.JarSigner.Builder" class in "jdk.jartool" module, update the javadoc of getDefaultDigestAlgorithm() method and getDefaultSignatureAlgorithm(PrivateKey key) method.

             /**
              * Gets the default digest algorithm.
              *
    -         * @implNote This implementation returns "SHA-256". The value may
    +         * @implNote This implementation returns "SHA-384". The value may
              * change in the future.
              *
              * @return the default digest algorithm.
              */
             public static String getDefaultDigestAlgorithm() {

    
             /**
              * Gets the default signature algorithm for a private key.
    -         * For example, SHA256withRSA for a 2048-bit RSA key, and
    +         * For example, SHA384withRSA for a 2048-bit RSA key, and
              * SHA384withECDSA for a 384-bit EC key.
              *
              * @implNote This implementation makes use of comparable strengths
    -         * as defined in Tables 2 and 3 of NIST SP 800-57 Part 1-Rev.4.
    -         * Specifically, if a DSA or RSA key with a key size greater than 7680
    +         * as defined in Tables 2 and 3 of NIST SP 800-57 Part 1-Rev.5 as
    +         * well as NIST recommendations as appropriate.
    +         * Specifically, if an RSA key with a key size greater than 7680
              * bits, or an EC key with a key size greater than or equal to 512 bits,
              * SHA-512 will be used as the hash function for the signature.
    -         * If a DSA or RSA key has a key size greater than 3072 bits, or an
    -         * EC key has a key size greater than or equal to 384 bits, SHA-384 will
    -         * be used. Otherwise, SHA-256 will be used. The value may
    -         * change in the future.
    +         * Otherwise, SHA-384 will be used unless the key size is too small
    +         * for resulting signature algorithm. As for DSA keys, the SHA256withDSA
    +         * signature algorithm is returned regardless of key size.
    +         * The value may change in the future.
              *
              * @param key the private key.
              * @return the default signature algorithm. Returns null if a default
              *      signature algorithm cannot be found. In this case,
              *      {@link #signatureAlgorithm} must be called to specify a
              *      signature algorithm. Otherwise, the {@link #build} method
              *      will throw an {@link IllegalArgumentException}.
              */
             public static String getDefaultSignatureAlgorithm(PrivateKey key) {

2) Update keytool doc with the new default key size and algorithm. Diff provided below:
 

    --- a/closed/src/java.base/share/man/keytool.md
    +++ b/closed/src/java.base/share/man/keytool.md
    @@ -1300,12 +1300,13 @@
     
     ```
     -alias "mykey"
     
     -keysize
    -    2048 (when using -genkeypair and -keyalg is "RSA", "DSA", "RSASSA-PSS", or "DH")
    -    256 (when using -genkeypair and -keyalg is "EC")
    +    2048 (when using -genkeypair and -keyalg is "DSA")
    +    3072 (when using -genkeypair and -keyalg is "RSA", "RSASSA-PSS", or "DH")
    +    384 (when using -genkeypair and -keyalg is "EC")
         255 (when using -genkeypair and -keyalg is "EdDSA", or "XDH)
         56 (when using -genseckey and -keyalg is "DES")
         168 (when using -genseckey and -keyalg is "DESede")
     
     -validity 90
    @@ -1330,17 +1331,17 @@
     private key to provide an appropriate level of security strength as follows:
     
     keyalg      keysize   default sigalg
     -------     --------  --------------
     DSA         any size  SHA256withDSA
    -RSA         \<= 3072  SHA256withRSA
    +RSA         \< 624    SHA256withRSA (keysize is too small for using SHA-384)
                 \<= 7680  SHA384withRSA
                 \> 7680   SHA512withRSA
    -EC          \< 384    SHA256withECDSA
    -            \< 512    SHA384withECDSA
    -            = 512     SHA512withECDSA
    -RSASSA-PSS  \<= 3072  RSASSA-PSS (with SHA-256)
    +EC          \< 512    SHA384withECDSA
    +            \>= 512   SHA512withECDSA
    +RSASSA-PSS  \< 624    RSASSA-PSS (with SHA-256, keysize is too small for
    +                      using SHA-384)
                 \<= 7680  RSASSA-PSS (with SHA-384)
                 \> 7680   RSASSA-PSS (with SHA-512)
     EdDSA       255       Ed25519
                 448       Ed448
     Ed25519     255       Ed25519
    @@ -1551,13 +1552,13 @@
     The command creates the keystore named `mykeystore` in the working directory
     (provided it doesn't already exist), and assigns it the password specified by
     `-keypass`. It generates a public/private key pair for the entity whose
     distinguished name is `myname`, `mygroup`, `mycompany`, and a two-letter
     country code of `mycountry`. It uses the RSA key generation algorithm
    -to create the keys; both are 2048 bits
    +to create the keys; both are 3072 bits.
     
    -The command uses the default SHA256withRSA signature algorithm to create a
    +The command uses the default SHA384withRSA signature algorithm to create a
     self-signed certificate that includes the public key and the distinguished name
     information. The certificate is valid for 180 days, and is associated with the
     private key in a keystore entry referred to by `-alias business`. The private
     key is assigned the password specified by `-keypass`.
     

3) Update jarsigner doc with the new default key size and algorithm. Diff provided below:

    --- a/closed/src/jdk.jartool/share/man/jarsigner.md
    +++ b/closed/src/jdk.jartool/share/man/jarsigner.md
    @@ -235,28 +235,27 @@
     the private key:
     
     keyalg      keysize     default sigalg              block file extension
     -------     --------    --------------              --------------------
     DSA         any size    SHA256withDSA               .DSA
    -RSA         \<= 3072    SHA256withRSA               .RSA
    +RSA         \< 624      SHA256withRSA               .RSA
                 \<= 7680    SHA384withRSA
                 \> 7680     SHA512withRSA
    -EC          \< 384      SHA256withECDSA             .EC
    -            \< 512      SHA384withECDSA
    -            = 512       SHA512withECDSA
    -RSASSA-PSS  \<= 3072    RSASSA-PSS (with SHA-256)   .RSA
    +EC          \< 512      SHA384withECDSA             .EC
    +            \>= 512     SHA512withECDSA
    +RSASSA-PSS  \< 624      RSASSA-PSS (with SHA-256)   .RSA
                 \<= 7680    RSASSA-PSS (with SHA-384)
                 \> 7680     RSASSA-PSS (with SHA-512)
     EdDSA       255         Ed25519                     .EC
                 448         Ed448
    --------     --------  --------------                ------
    +-------     --------    --------------              ------
     
     * If an RSASSA-PSS key is encoded with parameters, then jarsigner will use the
     same parameters in the signature. Otherwise, jarsigner will use parameters that
     are determined by the size of the key as specified in the table above.
     For example, an 3072-bit RSASSA-PSS key will use RSASSA-PSS as the signature
    -algorithm and SHA-256 as the hash and MGF1 algorithms.
    +algorithm and SHA-384 as the hash and MGF1 algorithms.
     
     These default signature algorithms can be overridden by using the `-sigalg`
     option.
     
     The `jarsigner` command uses the `jdk.jar.disabledAlgorithms` and
    @@ -577,11 +576,11 @@
         the entries of a JAR file.
     
         For a list of standard message digest algorithm names, see Java Security
         Standard Algorithm Names.
     
    -    If this option isn't specified, then `SHA256` is used. There must either be
    +    If this option isn't specified, then `SHA-384` is used. There must either be
         a statically installed provider supplying an implementation of the
         specified algorithm or the user must specify one with the `-addprovider` or
         `-providerClass` options; otherwise, the command will not succeed.
     
     `-sigalg` *algorithm*
    @@ -680,11 +679,11 @@
         period-separated sets of non-negative digits like `1.2.3.4`, for example.
     
     `-tsadigestalg` *algorithm*
     :   Specifies the message digest algorithm that is used to generate the message
         imprint to be sent to the TSA server. If this option isn't specified,
    -    SHA-256 will be used.
    +    SHA-384 will be used.
     
         See [Supported Algorithms].
     
         For a list of standard message digest algorithm names, see Java Security
         Standard Algorithm Names.


Comments
Moving to Approved.
23-03-2022

[~mullan] The reference of "NIST SP 800-57 Part 1" is not new; it is there in earlier code already, I just updated the version number to the latest value. It is independent to CNSA guideline. The earlier impl of jarsigner is based solely on NIST SP800-57 part 1 which does not really go hand-in-hand with CNSA. After some discussion with Max, the result is a mixed approach of CNSA and NIST SP800-57 part 1. I can see your point to add it to the Problem/Summary though.
21-03-2022

[~valeriep] I think the CSR Summary or Problem section should also reference "NIST SP 800-57 Part 1-Rev.5" as that is also being used as a guideline for increasing the defaults, and you have referenced that within the JarSigner javadocs. Perhaps you could also summarize the relationship between the NIST and CNSA guidelines. Also, the Scope and Interface fields need to be filled in. I think the Scope is "JDK" since none of these new defaults are SE requirements. Interface Kind is probably "Other" and/or "API".
17-03-2022

Moving to Provisional.
15-03-2022