Class KeyDerivationFunction


  • public class KeyDerivationFunction
    extends java.lang.Object
    This class implements a Key Derivation Function (KDF) and supporting methods. A KDF is a function with which an input key (called the Key Derivation Key, or KDK) and other input data are used to securely generate (i.e., derive) keying material that can be employed by cryptographic algorithms.

    Acknowledgments: ESAPI's KDF is patterned after suggestions first made by cryptographer Dr. David A. Wagner and later extended to follow KDF in counter mode as specified by section 5.1 of NIST SP 800-108. Jeffrey Walton and the NSA also made valuable suggestions regarding the modeling of the method, computeDerivedKey(SecretKey, int, String).

    Since:
    2.0
    Author:
    kevin.w.wall@gmail.com
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static int kdfVersion  
      static int originalVersion
      Used to support backward compatibility.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      javax.crypto.SecretKey computeDerivedKey​(javax.crypto.SecretKey keyDerivationKey, int keySize, java.lang.String purpose)
      The method is ESAPI's Key Derivation Function (KDF) that computes a derived key from the keyDerivationKey for either encryption / decryption or for authentication.
      static KeyDerivationFunction.PRF_ALGORITHMS convertIntToPRF​(int selection)  
      static KeyDerivationFunction.PRF_ALGORITHMS convertNameToPRF​(java.lang.String prfAlgName)  
      java.lang.String getContext()
      Return the optional 'context' that typically contains information related to the keying material, such as the identities of the message sender and recipient.
      java.lang.String getPRFAlgName()
      Return the name of the algorithm for the Pseudo Random Function (PRF) that is being used.
      int getVersion()
      Return the version used for backward compatibility.
      static boolean isValidPRF​(java.lang.String prfAlgName)
      Check if specified algorithm name is a valid PRF that can be used.
      static void main​(java.lang.String[] args)
      Print list of ESAPI supported pseudo-random functions for KDF and KDF version information.
      void setContext​(java.lang.String context)
      Set the 'context' as specified by NIST Special Publication 800-108.
      void setVersion​(int version)
      Set version so backward compatibility can be supported.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • KeyDerivationFunction

        public KeyDerivationFunction​(KeyDerivationFunction.PRF_ALGORITHMS prfAlg)
        Construct a KeyDerivationFunction.
        Parameters:
        prfAlg - Specifies a supported algorithm.
      • KeyDerivationFunction

        public KeyDerivationFunction()
        Construct a KeyDerivationFunction based on the ESAPI.property property, Encryptor.KDF.PRF.
    • Method Detail

      • getPRFAlgName

        public java.lang.String getPRFAlgName()
        Return the name of the algorithm for the Pseudo Random Function (PRF) that is being used.
        Returns:
        The PRF algorithm name.
      • setVersion

        public void setVersion​(int version)
                        throws java.lang.IllegalArgumentException
        Set version so backward compatibility can be supported. Used to set the version to some previous version so that previously encrypted data can be decrypted.
        Parameters:
        version - Date as a integer, in format of YYYYMMDD. Maximum version date is 99991231 (December 31, 9999).
        Throws:
        java.lang.IllegalArgumentException - If version is not within the valid range of [20110203, 99991231].
      • getVersion

        public int getVersion()
        Return the version used for backward compatibility.
        Returns:
        The KDF version #, in format YYYYMMDD, used for supporting backward compatibility.
      • setContext

        public void setContext​(java.lang.String context)
        Set the 'context' as specified by NIST Special Publication 800-108. NIST defines 'context' as "A binary string containing the information related to the derived keying material. It may include identities of parties who are deriving and/or using the derived keying material and, optionally, a once known by the parties who derive the keys." NIST SP 800-108 seems to imply that while 'context' is recommended, that it is optional. In section 7.6 of NIST 800-108, NIST uses "SHOULD" rather than "MUST":
        "Derived keying material should be bound to all relying entities and other information to identify the derived keying material. This is called context binding. In particular, the identity (or identifier, as the term is defined in [NIST SP 800-56A , sic] and [NIST SP 800-56B , sic]) of each entity that will access (meaning derive, hold, use, and/or distribute) any segment of the keying material should be included in the Context string input to the KDF, provided that this information is known by each entity who derives the keying material."
        The ISO/IEC's KDF2 uses a similar construction for their KDF and there 'context' data is not specified at all. Therefore, ESAPI 2.0's reference implementation, JavaEncryptor, chooses not to use 'context' at all.
        Parameters:
        context - Optional binary string containing information related to the derived keying material. By default (if this method is never called), the empty string is used. May have any value but null.
      • getContext

        public java.lang.String getContext()
        Return the optional 'context' that typically contains information related to the keying material, such as the identities of the message sender and recipient.
        Returns:
        The 'context' is returned.
        See Also:
        setContext(String)
      • computeDerivedKey

        public javax.crypto.SecretKey computeDerivedKey​(javax.crypto.SecretKey keyDerivationKey,
                                                        int keySize,
                                                        java.lang.String purpose)
                                                 throws java.security.NoSuchAlgorithmException,
                                                        java.security.InvalidKeyException,
                                                        EncryptionException
        The method is ESAPI's Key Derivation Function (KDF) that computes a derived key from the keyDerivationKey for either encryption / decryption or for authentication.

        CAUTION: If this algorithm for computing derived keys from the key derivation key is ever changed, we risk breaking backward compatibility of being able to decrypt data previously encrypted with earlier / different versions of this method. Therefore, do not change this unless you are 100% certain that what you are doing will NOT change either of the derived keys for ANY "key derivation key" AT ALL!!!

        NOTE: This method is generally not intended to be called separately. It is used by ESAPI's reference crypto implementation class JavaEncryptor and might be useful for someone implementing their own replacement class, but generally it is not something that is useful to application client code.

        Parameters:
        keyDerivationKey - A key used as an input to a key derivation function to derive other keys. This is the key that generally is created using some key generation mechanism such as CryptoHelper.generateSecretKey(String, int). The "input" key from which the other keys are derived. The derived key will have the same algorithm type as this key. This KDK cannot be null.
        keySize - The cipher's key size (in bits) for the keyDerivationKey. Must have a minimum size of 56 bits and be an integral multiple of 8-bits. Note: The derived key will have the same size as this.
        purpose - The purpose for the derived key. IMPORTANT: For the ESAPI reference implementation, JavaEncryptor, this must be either the string "encryption" or "authenticity", where "encryption" is used for creating a derived key to use for confidentiality, and "authenticity" is used for creating a derived key to use with a MAC to ensure message authenticity. However, since parameter serves the same purpose as the "Label" in section 5.1 of NIST SP 800-108, it really can be set to anything other than null or an empty string when called outside of ESAPI's JavaEncryptor reference implementation (but you must consistent).
        Returns:
        The derived SecretKey to be used according to the specified purpose.
        Throws:
        java.security.NoSuchAlgorithmException - The keyDerivationKey has an unsupported encryption algorithm or no current JCE provider supports requested Hmac algorithrm used for the PRF for key generation.
        EncryptionException - If "UTF-8" is not supported as an encoding, then this is thrown with the original UnsupportedEncodingException as the cause. (NOTE: This should never happen as "UTF-8" is supposed to be a common encoding supported by all Java implementations. Support for it is usually in rt.jar.) This exception is also thrown if the requested keySize parameter exceeds the length of the number of bytes provded in the keyDerivationKey parameter.
        java.security.InvalidKeyException - Likely indicates a coding error. Should not happen.
        EncryptionException - Throw for some precondition violations.
      • isValidPRF

        public static boolean isValidPRF​(java.lang.String prfAlgName)
        Check if specified algorithm name is a valid PRF that can be used.
        Parameters:
        prfAlgName - Name of the PRF algorithm; e.g., "HmacSHA1", "HmacSHA384", etc.
        Returns:
        True if prfAlgName is supported, otherwise false.
      • main

        public static final void main​(java.lang.String[] args)
        Print list of ESAPI supported pseudo-random functions for KDF and KDF version information.
        Parameters:
        args - Required, but not used.