Class CipherText

  • All Implemented Interfaces:
    java.io.Serializable

    public final class CipherText
    extends java.lang.Object
    implements java.io.Serializable
    A Serializable interface representing the result of encrypting plaintext and some additional information about the encryption algorithm, the IV (if pertinent), and an optional Message Authentication Code (MAC).

    Note that while this class is Serializable in the usual Java sense, ESAPI uses asPortableSerializedByteArray() for serialization. Not only is this serialization somewhat more compact, it is also portable across other ESAPI programming language implementations. However, Java serialization is supported in the event that one wishes to store CipherText in an HttpSession object.

    Copyright © 2009 - The OWASP Foundation

    Since:
    2.0
    Author:
    kevin.w.wall@gmail.com
    See Also:
    PlainText, Encryptor, Serialized Form
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static int cipherTextVersion  
    • Constructor Summary

      Constructors 
      Constructor Description
      CipherText()
      Default CTOR.
      CipherText​(CipherSpec cipherSpec)
      Construct from a CipherSpec object.
      CipherText​(CipherSpec cipherSpec, byte[] cipherText)
      Construct from a CipherSpec object and the raw ciphertext.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      byte[] asPortableSerializedByteArray()
      Return this CipherText object as a portable (i.e., network byte ordered) serialized byte array.
      protected boolean canEqual​(java.lang.Object other)
      Needed for correct definition of equals for general classes.
      void computeAndStoreMAC​(javax.crypto.SecretKey authKey)
      Compute and store the Message Authentication Code (MAC) if the ESAPI property Encryptor.CipherText.useMAC is set to true.
      boolean equals​(java.lang.Object other)
      static CipherText fromPortableSerializedBytes​(byte[] bytes)
      Create a CipherText object from what is supposed to be a portable serialized byte array, given in network byte order, that represents a valid, previously serialized CipherText object using asPortableSerializedByteArray().
      java.lang.String getBase64EncodedRawCipherText()
      Return a base64-encoded representation of the raw ciphertext alone.
      int getBlockSize()
      Retrieve the block size (in bytes!) of the cipher used for encryption.
      java.lang.String getCipherAlgorithm()
      Obtain the name of the cipher algorithm used for encrypting the plaintext.
      java.lang.String getCipherMode()
      Get the name of the cipher mode used to encrypt some plaintext.
      java.lang.String getCipherTransformation()
      Obtain the String representing the cipher transformation used to encrypt the plaintext.
      java.lang.String getEncodedIVCipherText()
      Return the ciphertext as a base64-encoded String.
      long getEncryptionTimestamp()
      Get stored time stamp representing when data was encrypted.
      byte[] getIV()
      Return the initialization vector (IV) used to encrypt the plaintext if applicable.
      KeyDerivationFunction.PRF_ALGORITHMS getKDF_PRF()  
      int getKDFInfo()
      Based on the KDF version and the selected MAC algorithm for the KDF PRF, calculate the 32-bit quantity representing these.
      int getKDFVersion()  
      int getKeySize()
      Retrieve the key size used with the cipher algorithm that was used to encrypt data to produce this ciphertext.
      java.lang.String getPaddingScheme()
      Get the name of the padding scheme used to encrypt some plaintext.
      byte[] getRawCipherText()
      Get the raw ciphertext byte array resulting from encrypting some plaintext.
      int getRawCipherTextByteLength()
      Get number of bytes in raw ciphertext.
      byte[] getSeparateMAC()
      Return the separately calculated Message Authentication Code (MAC) that is computed via the computeAndStoreMAC(SecretKey authKey) method.
      int hashCode()
      boolean requiresIV()
      Return true if the cipher mode used requires an IV.
      void setCiphertext​(byte[] ciphertext)
      Set the raw ciphertext.
      void setIVandCiphertext​(byte[] iv, byte[] ciphertext)
      Set the IV and raw ciphertext.
      void setKDF_PRF​(int prfSelection)  
      void setKDFVersion​(int vers)  
      java.lang.String toString()
      More useful toString() method.
      boolean validateMAC​(javax.crypto.SecretKey authKey)
      Validate the message authentication code (MAC) associated with the ciphertext.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • CipherText

        public CipherText()
        Default CTOR. Takes all the defaults from the ESAPI.properties, or default values from initial values from this class (when appropriate) when they are not set in ESAPI.properties.
      • CipherText

        public CipherText​(CipherSpec cipherSpec,
                          byte[] cipherText)
                   throws EncryptionException
        Construct from a CipherSpec object and the raw ciphertext.
        Parameters:
        cipherSpec - The cipher specification to use.
        cipherText - The raw ciphertext bytes to use.
        Throws:
        EncryptionException - Thrown if cipherText is null or empty array.
    • Method Detail

      • fromPortableSerializedBytes

        public static CipherText fromPortableSerializedBytes​(byte[] bytes)
                                                      throws EncryptionException
        Create a CipherText object from what is supposed to be a portable serialized byte array, given in network byte order, that represents a valid, previously serialized CipherText object using asPortableSerializedByteArray().
        Parameters:
        bytes - A byte array created via CipherText.asPortableSerializedByteArray()
        Returns:
        A CipherText object reconstructed from the byte array.
        Throws:
        EncryptionException
        See Also:
        asPortableSerializedByteArray()
      • getCipherTransformation

        public java.lang.String getCipherTransformation()
        Obtain the String representing the cipher transformation used to encrypt the plaintext. The cipher transformation represents the cipher algorithm, the cipher mode, and the padding scheme used to do the encryption. An example would be "AES/CBC/PKCS5Padding". See Appendix A in the Java Cryptography Architecture Reference Guide for information about standard supported cipher transformation names.

        The cipher transformation name is usually sufficient to be passed to Cipher.getInstance(String) to create a Cipher object to decrypt the ciphertext.

        Returns:
        The cipher transformation name used to encrypt the plaintext resulting in this ciphertext.
      • getCipherAlgorithm

        public java.lang.String getCipherAlgorithm()
        Obtain the name of the cipher algorithm used for encrypting the plaintext.
        Returns:
        The name as the cryptographic algorithm used to perform the encryption resulting in this ciphertext.
      • getKeySize

        public int getKeySize()
        Retrieve the key size used with the cipher algorithm that was used to encrypt data to produce this ciphertext.
        Returns:
        The key size in bits. We work in bits because that's the crypto way!
      • getBlockSize

        public int getBlockSize()
        Retrieve the block size (in bytes!) of the cipher used for encryption. (Note: If an IV is used, this will also be the IV length.)
        Returns:
        The block size in bytes. (Bits, bytes! It's confusing I know. Blame the cryptographers; we've just following convention.)
      • getCipherMode

        public java.lang.String getCipherMode()
        Get the name of the cipher mode used to encrypt some plaintext.
        Returns:
        The name of the cipher mode used to encrypt the plaintext resulting in this ciphertext. E.g., "CBC" for "cipher block chaining", "ECB" for "electronic code book", etc.
      • getPaddingScheme

        public java.lang.String getPaddingScheme()
        Get the name of the padding scheme used to encrypt some plaintext.
        Returns:
        The name of the padding scheme used to encrypt the plaintext resulting in this ciphertext. Example: "PKCS5Padding". If no padding was used "None" is returned.
      • getIV

        public byte[] getIV()
        Return the initialization vector (IV) used to encrypt the plaintext if applicable.
        Returns:
        The IV is returned if the cipher mode used to encrypt the plaintext was not "ECB". ECB mode does not use an IV so in that case, null is returned.
      • requiresIV

        public boolean requiresIV()
        Return true if the cipher mode used requires an IV. Usually this will be true unless ECB mode (which should be avoided whenever possible) is used.
      • getRawCipherText

        public byte[] getRawCipherText()
        Get the raw ciphertext byte array resulting from encrypting some plaintext.
        Returns:
        A copy of the raw ciphertext as a byte array.
      • getRawCipherTextByteLength

        public int getRawCipherTextByteLength()
        Get number of bytes in raw ciphertext. Zero is returned if ciphertext has not yet been stored.
        Returns:
        The number of bytes of raw ciphertext; 0 if no raw ciphertext has been stored.
      • getBase64EncodedRawCipherText

        public java.lang.String getBase64EncodedRawCipherText()
        Return a base64-encoded representation of the raw ciphertext alone. Even in the case where an IV is used, the IV is not prepended before the base64-encoding is performed.

        If there is a need to store an encrypted value, say in a database, this is not the method you should use unless you are using are storing the IV separately (i.e., in a separate DB column), which doesn't make a lot of sense. Normally, you should prefer the method getEncodedIVCipherText() instead as it will return the IV prepended to the ciphertext.

        See Also:
        getEncodedIVCipherText()
      • getEncodedIVCipherText

        public java.lang.String getEncodedIVCipherText()
        Return the ciphertext as a base64-encoded String. If an IV was used, the IV if first prepended to the raw ciphertext before base64-encoding. If an IV is not used, then this method returns the same value as getBase64EncodedRawCipherText().

        Returns:
        The base64-encoded ciphertext or base64-encoded IV + ciphertext.
        See Also:
        getBase64EncodedRawCipherText()
      • computeAndStoreMAC

        public void computeAndStoreMAC​(javax.crypto.SecretKey authKey)
        Compute and store the Message Authentication Code (MAC) if the ESAPI property Encryptor.CipherText.useMAC is set to true. If it is, the MAC is conceptually calculated as:
              authKey = DerivedKey(secret_key, "authenticate")
              HMAC-SHA1(authKey, IV + secret_key)
         
        where derived key is an HMacSHA1, possibly repeated multiple times. (See CryptoHelper.computeDerivedKey(SecretKey, int, String) for details.)

        Perceived Benefits: There are certain cases where if an attacker is able to change the IV. When one uses a authenticity key that is derived from the "master" key, it also makes it possible to know when the incorrect key was attempted to be used to decrypt the ciphertext.

        NOTE: The purpose of this MAC (which is always computed by the ESAPI reference model implementing Encryptor) is to ensure the authenticity of the IV and ciphertext. Among other things, this prevents an adversary from substituting the IV with one of their own choosing. Because we don't know whether or not the recipient of this CipherText object will want to validate the authenticity or not, the reference implementation of Encryptor always computes it and includes it. The recipient of the ciphertext can then choose whether or not to validate it.

        Parameters:
        authKey - The secret key that is used for proving authenticity of the IV and ciphertext. This key should be derived from the SecretKey passed to the Encryptor.encrypt(javax.crypto.SecretKey, PlainText) and Encryptor.decrypt(javax.crypto.SecretKey, CipherText) methods or the "master" key when those corresponding encrypt / decrypt methods are used. This authenticity key should be the same length and for the same cipher algorithm as this SecretKey. The method CryptoHelper.computeDerivedKey(SecretKey, int, String) is a secure way to produce this derived key.
      • validateMAC

        public boolean validateMAC​(javax.crypto.SecretKey authKey)
        Validate the message authentication code (MAC) associated with the ciphertext. This is mostly meant to ensure that an attacker has not replaced the IV or raw ciphertext with something arbitrary. Note however that it will not detect the case where an attacker simply substitutes one valid ciphertext with another ciphertext.
        Parameters:
        authKey - The secret key that is used for proving authenticity of the IV and ciphertext. This key should be derived from the SecretKey passed to the Encryptor.encrypt(javax.crypto.SecretKey, PlainText) and Encryptor.decrypt(javax.crypto.SecretKey, CipherText) methods or the "master" key when those corresponding encrypt / decrypt methods are used. This authenticity key should be the same length and for the same cipher algorithm as this SecretKey. The method CryptoHelper.computeDerivedKey(SecretKey, int, String) is a secure way to produce this derived key.
        Returns:
        True if the ciphertext has not be tampered with, and false otherwise.
      • asPortableSerializedByteArray

        public byte[] asPortableSerializedByteArray()
                                             throws EncryptionException
        Return this CipherText object as a portable (i.e., network byte ordered) serialized byte array. Note this is not the same as returning a serialized object using Java serialization. Instead this is a representation that all ESAPI implementations will use to pass ciphertext between different programming language implementations.
        Returns:
        A network byte-ordered serialized representation of this object.
        Throws:
        EncryptionException
      • setIVandCiphertext

        public void setIVandCiphertext​(byte[] iv,
                                       byte[] ciphertext)
                                throws EncryptionException
        Set the IV and raw ciphertext.
        Parameters:
        iv - The initialization vector.
        ciphertext - The raw ciphertext.
        Throws:
        EncryptionException
      • getKDFVersion

        public int getKDFVersion()
      • setKDFVersion

        public void setKDFVersion​(int vers)
      • setKDF_PRF

        public void setKDF_PRF​(int prfSelection)
      • getEncryptionTimestamp

        public long getEncryptionTimestamp()
        Get stored time stamp representing when data was encrypted.
      • getSeparateMAC

        public byte[] getSeparateMAC()
        Return the separately calculated Message Authentication Code (MAC) that is computed via the computeAndStoreMAC(SecretKey authKey) method.
        Returns:
        The copy of the computed MAC, or null if one is not used.
      • toString

        public java.lang.String toString()
        More useful toString() method.
        Overrides:
        toString in class java.lang.Object
      • equals

        public boolean equals​(java.lang.Object other)
        Overrides:
        equals in class java.lang.Object
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • canEqual

        protected boolean canEqual​(java.lang.Object other)
        Needed for correct definition of equals for general classes. (Technically not needed for 'final' classes though like this class though; this will just allow it to work in the future should we decide to allow * sub-classing of this class.)

        See