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

Signed JAR support for RSASSA-PSS and EdDSA

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 16
    • security-libs
    • None
    • behavioral
    • minimal
    • For the RFC 6211 support, we have long been supporting the signed attributes. So the newly signed jar will be verified correctly by older JDK releases. The CMSAlgorithmProtection will be silently ignored.
    • add/remove/modify command line option, File or wire format
    • JDK

      Summary

      Add the capability to sign JAR files with RSASSA-PSS and EdDSA signatures algorithms.

      Problem

      We've added support for RSASSA-PSS (JDK-8146293) since JDK 11 and EdDSA (JDK-8166597) recently, and we should support them in signed JAR files as well. The usage of the 2 algorithms in Cryptographic Message Syntax (CMS, which is the format we use for signature block files inside a signed JAR file) are defined in https://tools.ietf.org/html/rfc4056 and https://www.rfc-editor.org/rfc/rfc8419.html, respectively.

      Solution

      Support signing of a JAR file using these algorithms, which means:

      1. RSASSA-RSS and EdDSA keys can be used to sign a JAR file
      2. New -sigalg options: RSASSA-PSS, EdDSA, Ed25519, and Ed448 (case-insensitive).

      We will also support loading signed JAR files signed with these new algorithms.

      We will support the RFC 6211 CMSAlgorithmProtection attribute on all algorithms to protect against algorithm substitution attacks (especially for the new RSASSA-PSS algorithm). This is the default style used by openssl cms command and BountyCastle's JcaSignerInfoGeneratorBuilder class. Users can turn off this feature by setting the JarSigner.Builder property directsign to true or adding the -directsign option to the jarsigner tool, which means there will be no signed attributes and the signature is calculated on the .SF file directly.

      Specification

      The JarSigner API

      package jdk.security.jarsigner;

        public final class JarSigner {
            public static class Builder {
                /**
                 * Sets an additional implementation-specific property indicated by
                 * the specified key.
                 ....
      +          * <li>"directsign": "true" if the signature is calculated on the
      +          * content directly, "false" if it's calculated on signed attributes
      +          * which itself is calculated from the content and stored in the
      +          * signer's SignerInfo. Default "false".
                 ....
                 */
                public Builder setProperty(String key, String value);

      The jarsigner tool

      The -sigalg options will support 4 new values: RSASSA-PSS, EdDSA, Ed25519 and Ed448. The RSASSA-PSS algorithm can be used for both an RSA key or an RSASSA-PSS key. The EdDSA algorithm can only be used for an EdDSA key. The Ed25519 algorithm can only be used for a 255-bit EdDSA key. The Ed448 algorithm can only be used for a 448-bit EdDSA key. The option values are case-insensitive.

      The block file extension for RSASSA-PSS is still .RSA. The block file extension for EdDSA, Ed25519 or Ed448 is still .EC.

      A new -directsign option will be supported.

      The tooldoc

      In the jarsigner man page,

      1. Add info on RSASSA-PSS and EdDSA keys to the table in "Supported Algorithms".
      2. Add a new column "block file extension" to this table.
      3. The document was written when we only support DSA keys, and it uses the ".DSA" word everywhere. Rename it to "signature block file".
      4. Always use ".RSA" in examples.

      The exact diff for the jarsigner man page:

      @@ -226,18 +226,30 @@
      
       ## Supported Algorithms
      
       By default, the `jarsigner` command signs a JAR file using one of the following
      -algorithms files depending on the type and size of the private key:
      +algorithms and block file extensions depending on the type and size of
      +the private key:
      
      -keyalg   keysize   default sigalg
      --------  --------  --------------
      -DSA      any size  SHA256withDSA
      -RSA      \<= 3072  SHA256withRSA
      -         \<= 7680  SHA384withRSA
      -         \> 7680   SHA512withRSA
      -EC       \< 384    SHA256withECDSA
      -         \< 512    SHA384withECDSA
      -         = 512     SHA512withECDSA
      --------  --------  --------------
      +keyalg      keysize     default sigalg              block file extension
      +-------     --------    --------------              --------------------
      +DSA         any size    SHA256withDSA               .DSA
      +RSA         \<= 3072    SHA256withRSA               .RSA
      +            \<= 7680    SHA384withRSA
      +            \> 7680     SHA512withRSA
      +EC          \< 384      SHA256withECDSA             .EC
      +            \< 512      SHA384withECDSA
      +            = 512       SHA512withECDSA
      +RSASSA-PSS  \<= 3072    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.
      
       These default signature algorithms can be overridden by using the `-sigalg`
       option.
      @@ -274,10 +286,11 @@
      
       The base file names for these two files come from the value of the `-sigfile`
       option. For example, when the option is `-sigfile MKSIGN`, the files are named
      -`MKSIGN.SF` and `MKSIGN.DSA`
      +`MKSIGN.SF` and `MKSIGN.RSA`. In this document, we assume the signer always
      +uses an RSA key.
      
       If no `-sigfile` option appears on the command line, then the base file name
      -for the `.SF` and `.DSA` files is the first 8 characters of the alias name
      +for the `.SF` and the signature block files is the first 8 characters of the alias name
       specified on the command line, all converted to uppercase. If the alias name
       has fewer than 8 characters, then the full alias name is used. If the alias
       name contains any characters that aren't allowed in a signature file name, then
      @@ -318,7 +331,8 @@
       file. This file also contains, encoded inside it, the certificate or
       certificate chain from the keystore that authenticates the public key
       corresponding to the private key used for signing. The file has the extension
      -`.DSA`, `.RSA`, or `.EC`, depending on the digest algorithm used.
      +`.DSA`, `.RSA`, or `.EC`, depending on the key algorithm used. See the table
      +in [Supported Algorithms].
      
       ## Signature Time Stamp
      
      @@ -344,9 +358,9 @@
       1.  Verify the signature of the `.SF` file.
      
           The verification ensures that the signature stored in each signature block
      -    (`.DSA`) file was generated using the private key corresponding to the
      +    file was generated using the private key corresponding to the
           public key whose certificate (or certificate chain) also appears in the
      -    `.DSA` file. It also ensures that the signature is a valid signature of the
      +    signature block file. It also ensures that the signature is a valid signature of the
           corresponding signature (`.SF`) file, and thus the `.SF` file wasn't
           tampered with.
      
      @@ -403,15 +417,15 @@
       jarsigner myBundle.jar kevin
       ```
      
      -When a JAR file is signed multiple times, there are multiple `.SF` and `.DSA`
      -files in the resulting JAR file, one pair for each signature. In the previous
      +When a JAR file is signed multiple times, there are multiple `.SF` and signature 
      +block files in the resulting JAR file, one pair for each signature. In the previous
       example, the output JAR file includes files with the following names:
      
       ```
       SUSAN.SF
      -SUSAN.DSA
      +SUSAN.RSA
       KEVIN.SF
      -KEVIN.DSA
      +KEVIN.RSA
       ```
      
       ## Options for jarsigner
      @@ -529,18 +543,18 @@
           Certificate Encoding Standard](http://tools.ietf.org/html/rfc1421).
      
       `-sigfile` *file*
      -:   Specifies the base file name to be used for the generated `.SF` and `.DSA`
      +:   Specifies the base file name to be used for the generated `.SF` and signature block
           files. For example, if file is `DUKESIGN`, then the generated `.SF` and
      -    `.DSA` files are named `DUKESIGN.SF` and `DUKESIGN.DSA`, and placed in the
      +    signature block files are named `DUKESIGN.SF` and `DUKESIGN.RSA`, and placed in the
           `META-INF` directory of the signed JAR file.
      
           The characters in the file must come from the set `a-zA-Z0-9_-`. Only
           letters, numbers, underscore, and hyphen characters are allowed. All
      -    lowercase characters are converted to uppercase for the `.SF` and `.DSA`
      +    lowercase characters are converted to uppercase for the `.SF` and signature block
           file names.
      
           If no `-sigfile` option appears on the command line, then the base file
      -    name for the `.SF` and `.DSA` files is the first 8 characters of the alias
      +    name for the `.SF` and signature block files is the first 8 characters of the alias
           name specified on the command line, all converted to upper case. If the
           alias name has fewer than 8 characters, then the full alias name is used.
           If the alias name contains any characters that aren't valid in a signature
      @@ -607,7 +621,7 @@
       :   If the `-certs` option appears on the command line with the `-verify` and
           `-verbose` options, then the output includes certificate information for
           each signer of the JAR file. This information includes the name of the type
      -    of certificate (stored in the `.DSA` file) that certifies the signer's
      +    of certificate (stored in the signature block file) that certifies the signer's
           public key, and if the certificate is an X.509 certificate (an instance of
           the `java.security.cert.X509Certificate`), then the distinguished name of
           the signer.
      @@ -668,15 +682,22 @@ the following standards:
           Standard Algorithm Names.
      
       `-internalsf`
      -:   In the past, the `.DSA` (signature block) file generated when a JAR file
      +:   In the past, the signature block file generated when a JAR file
           was signed included a complete encoded copy of the `.SF` file (signature
           file) also generated. This behavior has been changed. To reduce the overall
      -    size of the output JAR file, the `.DSA` file by default doesn't contain a
      +    size of the output JAR file, the signature block file by default doesn't contain a
           copy of the `.SF` file anymore. If `-internalsf` appears on the command
           line, then the old behavior is utilized. This option is useful for testing.
           In practice, don't use the `-internalsf` option because it incurs higher
           overhead.
      
      +`-directsign`
      +:   By default, jarsigner stores the hash of the `.SF` file and possibly
      +    other information in a SignerInfo signedAttributes field, and then
      +    calculates the signature on this field. If this option is set, no
      +    SignerInfo signedAttributes field is generated and the signature is
      +    calculated on the `.SF` file directly.
      +
       `-sectionsonly`
       :   If the `-sectionsonly` option appears on the command line, then the `.SF`
      
       file (signature file) generated when a JAR file is signed doesn't include a
      @@ -927,8 +941,8 @@
           jane`
      
       There is no `-sigfile` specified in the previous command so the generated `.SF`
      -and `.DSA` files to be placed in the signed JAR file have default names based
      -on the alias name. They are named `JANE.SF` and `JANE.DSA`.
      +and signature block files to be placed in the signed JAR file have default names based
      +on the alias name. They are named `JANE.SF` and `JANE.RSA`.
      
       If you want to be prompted for the store password and the private key password,
       then you could shorten the previous command to the following:

      In the keytool man page, document the details on key pair generation for RSASSA-PSS and EdDSA keys (in retrospec).

      The exact diff for the keytool man page:

      @@ -1221,9 +1221,9 @@
       -alias "mykey"
      
       -keysize
      -    2048 (when using -genkeypair and -keyalg is "RSA")
      -    2048 (when using -genkeypair and -keyalg is "DSA")
      +    2048 (when using -genkeypair and -keyalg is "RSA", "DSA", or "RSASSA-PSS")
           256 (when using -genkeypair and -keyalg is "EC")
      +    255 (when using -genkeypair and -keyalg is "EdDSA")
           56 (when using -genseckey and -keyalg is "DES")
           168 (when using -genseckey and -keyalg is "DESede")
      
      @@ -1248,16 +1248,32 @@
       algorithm (`-sigalg` option) is derived from the algorithm of the underlying
       private key to provide an appropriate level of security strength as follows:
      
      -keyalg   keysize   default sigalg
      --------  --------  --------------
      -DSA      any size  SHA256withDSA
      -RSA      \<= 3072  SHA256withRSA
      -         \<= 7680  SHA384withRSA
      -         \> 7680   SHA512withRSA
      -EC       \< 384    SHA256withECDSA
      -         \< 512    SHA384withECDSA
      -         = 512     SHA512withECDSA
      --------  --------  --------------
      +keyalg      keysize   default sigalg
      +-------     --------  --------------
      +DSA         any size  SHA256withDSA
      +RSA         \<= 3072  SHA256withRSA
      +            \<= 7680  SHA384withRSA
      +            \> 7680   SHA512withRSA
      +EC          \< 384    SHA256withECDSA
      +            \< 512    SHA384withECDSA
      +            = 512     SHA512withECDSA
      +RSASSA-PSS  \<= 3072  RSASSA-PSS (with SHA-256)
      +            \<= 7680  RSASSA-PSS (with SHA-384)
      +            \> 7680   RSASSA-PSS (with SHA-512)
      +EdDSA       255       Ed25519
      +            448       Ed448
      +Ed25519     255       Ed25519
      +Ed448       448       Ed448
      +-------     --------  --------------
      +
      +* An RSASSA-PSS signature algorithm uses a `MessageDigest`
      +algorithm as its hash and MGF1 algorithms.
      +
      +* EdDSA supports 2 key sizes: Ed25519 and Ed448. When generating an EdDSA key
      +pair using `-keyalg EdDSA`, a user can specify `-keysize 255` or `-keysize 448`
      +to generate Ed25519 or Ed448 key pairs. When no `-keysize` is specified, an
      +Ed25519 key pair is generated. A user can also directly specify `-keyalg Ed25519`
      +or `-keyalg Ed448` to generate a key pair with the expected key size.
      
       **Note:**

            weijun Weijun Wang
            weijun Weijun Wang
            Sean Mullan, Valerie Peng
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: