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

Customizing the generation of a PKCS12 keystore

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 12
    • Component/s: security-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      Hide
      If a keystore is created with a newly added Mac algorithm, it will not be parsed correctly by an old JDK release. 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.
      Show
      If a keystore is created with a newly added Mac algorithm, it will not be parsed correctly by an old JDK release. 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.
    • Interface Kind:
      System or security property
    • Scope:
      SE

      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, the current default keystore type, always requires a password to access the certificate stored inside it. This is not the same as the previously 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

      (Note that the only SE-specific change is the addition of the new HmacPBE algorithm names to the Standard Algorithm Names Specification. The rest of the changes are JDK-specific.)

      1) Add the following lines into conf/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

      They will be added to the Mac section of the Java Security Standard Algorithm Names Specification, and the SunJCE/Mac section of the JDK Providers Documentation.

      3) Make some changes to java.security.KeyStore$PasswordProtection in KeyStore.java. First, the security properties were never meant to be a part of the Java SE spec and we do not require all third-party providers to implement them. These sentences should have been put under an @implNote tag. Second, we have actually never implemented the keystore.<type>.keyProtectionAlgorithm properties for other keystore types like JKS and JCEKS. Since the settings for PKCS12 have been expanded this time and well-documented inside java.security, we can simply remove the sentences here.

       /**
        * Gets the name of the protection algorithm.
        * If none was set then the keystore provider will use its default
      - * protection algorithm. The name of the default protection algorithm
      - * for a given keystore type is set using the
      - * {@code 'keystore.<type>.keyProtectionAlgorithm'} security property.
      - * For example, the
      - * {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the
      - * name of the default key protection algorithm used for PKCS12
      - * keystores. If the security property is not set, an
      - * implementation-specific algorithm will be used.
      + * protection algorithm.
        *
        * @return the algorithm name, or {@code null} if none was set
        *
        * @since 1.8
        */
       public String getProtectionAlgorithm()

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                weijun Weijun Wang
                Reporter:
                vinnie Vincent Ryan
                Reviewed By:
                Sean Mullan
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: