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

Customizing the generation of a PKCS12 keystore

    XMLWordPrintable

Details

    • behavioral
    • low
    • If a keystore is created with a newly added Mac algorithm, it will not be parsed correctly by JDK 7u. If a keystore is created with a non-default encryption algorithm, it will not be parsed correctly by JDK 7u if the algorithm does not exist there.
    • System or security property
    • JDK

    Description

      Summary

      Define some system/Security properties to determine what parameters should be used when generating a PKCS12 keystore.

      Problem

      1. JDK's PKCS 12 keystore implementation hardcodes PBE (password based encryption) algorithms and other parameters.

      2. JDK's PKCS 12 keystore always requires a password to access the certificate stored inside it. This is not the same as default keystore type JKS, where the password is only used for integrity check. This inconsistency is breaking some existing applications where no password is given.

      Solution

      See spec.

      We would also like to take this chance to change the name of a security property from keystore.PKCS12.keyProtectionAlgorithm to keystore.pkcs12.keyProtectionAlgorithm described in KeyStore.java. Traditionally, lowercase characters are used in security property names. Also, there is no behavior change for this update, since the implementation is already reading names in both lowercase and uppercase (in this order).

      keytool will be updated to recognize the password-less pkcs12 keystore format (i.e. both certProtectionAlgorithm and macAlgorithm being NONE), where it should not prompt for store password when creating or reading such a keystore.

      Specification

      1) Add the following lines into jre/lib/security/java.security:

      #
      # PKCS12 KeyStore properties
      #
      # The following properties, if configured, are used by the PKCS12 KeyStore
      # implementation during the creation of a new keystore. Several of the
      # properties may also be used when modifying an existing keystore. The
      # properties can be overridden by a KeyStore API that specifies its own
      # algorithms and parameters.
      #
      # If an existing PKCS12 keystore is loaded and then stored, the algorithm and
      # parameter used to generate the existing Mac will be reused. If the existing
      # keystore does not have a Mac, no Mac will be created while storing. If there
      # is at least one certificate in the existing keystore, the algorithm and
      # parameter used to encrypt the last certificate in the existing keystore will
      # be reused to encrypt all certificates while storing. If the last certificate
      # in the existing keystore is not encrypted, all certificates will be stored
      # unencrypted. If there is no certificate in the existing keystore, any newly
      # added certificate will be encrypted (or stored unencrypted if algorithm
      # value is "NONE") using the "keystore.pkcs12.certProtectionAlgorithm" and
      # "keystore.pkcs12.certPbeIterationCount" values defined here. Existing private
      # and secret key(s) are not changed. Newly set private and secret key(s) will
      # be encrypted using the "keystore.pkcs12.keyProtectionAlgorithm" and
      # "keystore.pkcs12.keyPbeIterationCount" values defined here.
      #
      # In order to apply new algorithms and parameters to all entries in an
      # existing keystore, one can create a new keystore and add entries in the
      # existing keystore into the new keystore. This can be achieved by calling the
      # "keytool -importkeystore" command.
      #
      # If a system property of the same name is also specified, it supersedes the
      # security property value defined here.
      #
      # If the property is set to an illegal value, for example,
      # an iteration count that is not a positive integer, or an unknown algorithm
      # name, an exception will be thrown when the property is used.
      # If the property is not set or empty, a default value will be used.
      #
      # Note: These properties are currently used by the JDK Reference implementation.
      # They are not guaranteed to be examined and used by other implementations.
      
      # The algorithm used to encrypt a certificate. This can be any non-Hmac PBE
      # algorithm defined in the Cipher section of the Java Security Standard
      # Algorithm Names Specification. When set to "NONE", the certificate
      # is not encrypted. The default value is "PBEWithSHA1AndRC2_40".
      #keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40
      
      # The iteration count used by the PBE algorithm when encrypting a certificate.
      # This value must be a positive integer. The default value is 50000.
      #keystore.pkcs12.certPbeIterationCount = 50000
      
      # The algorithm used to encrypt a private key or secret key. This can be
      # any non-Hmac PBE algorithm defined in the Cipher section of the Java
      # Security Standard Algorithm Names Specification. The value must not be "NONE".
      # The default value is "PBEWithSHA1AndDESede".
      #keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede
      
      # The iteration count used by the PBE algorithm when encrypting a private key
      # or a secret key. This value must be a positive integer. The default value
      # is 50000.
      #keystore.pkcs12.keyPbeIterationCount = 50000
      
      # The algorithm used to calculate the optional MacData at the end of a PKCS12
      # file. This can be any HmacPBE algorithm defined in the Mac section of the
      # Java Security Standard Algorithm Names Specification. When set to "NONE",
      # no Mac is generated. The default value is "HmacPBESHA1".
      #keystore.pkcs12.macAlgorithm = HmacPBESHA1
      
      # The iteration count used by the MacData algorithm. This value must be a
      # positive integer. The default value is 100000.
      #keystore.pkcs12.macIterationCount = 100000

      Below are some explanations on why existing encrypted private keys retain their different algorithms but the encrypted certificates must use the same algorithm:

      The KeyStore class is designed to be protected by a single store password and multiple key passwords. Once a keystore is loaded (after providing the store password), all certificates are in clear text, while reading each key in a key entry needs an individual key password. This means we must encrypt all certificates using the same store password. If different algorithms are used to encrypt different certificates, an attacker can decrypt the one using the weakest algorithm and then gain access to others using stronger algorithms.

      In fact, storing certificates using the same algorithm is doable since they are already decrypted after loading and the store method has an argument for the new store password. On the other hand, one can only call getKey(alias, password) to get a decrypted key and the key is still stored encrypted inside a KeyStore object, and there is no way to re-encrypt all keys with a single algorithm when storing them.

      2) Add several new Mac algorithms to the SunJCE provider:

      HmacPBESHA1
      HmacPBESHA224
      HmacPBESHA256
      HmacPBESHA384
      HmacPBESHA512
      HmacPBESHA512/224
      HmacPBESHA512/256

      Difference from JDK11 version

      8u will only support passwordless keystores if 'storetype' is set to case-insensitive 'pkcs12' (either by Keytool parameter explicitly or taken from the keystore.type security property) AND if the security provider in use is SunJSSE.

      Attachments

        Issue Links

          Activity

            People

              abakhtin Alexey Bakhtin
              vinnie Vincent Ryan
              Joe Darcy
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: