org.owasp.esapi.crypto
Class CipherText

java.lang.Object
  extended by org.owasp.esapi.crypto.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:
[email protected]
See Also:
PlainText, Encryptor, Serialized Form

Field Summary
static int cipherTextVersion
           
 
Constructor Summary
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
 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.
static long getSerialVersionUID()
          Deprecated. Use CipherText.cipherTextVersion instead. Will disappear as of ESAPI 2.1.
 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
 

Field Detail

cipherTextVersion

public static final int cipherTextVersion
See Also:
Constant Field Values
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)
Construct from a CipherSpec object. Still needs to have setCiphertext(byte[]) or setIVandCiphertext(byte[], byte[]) called to be usable.

Parameters:
cipherSpec - The cipher specification to use.

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 a fixed IV. If you are not using a fixed IV, you should normally use getEncodedIVCipherText() instead.

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().

Generally, this is the method that you should use unless you only are using a fixed IV and a storing that IV separately, in which case using getBase64EncodedRawCipherText() can reduce the storage overhead.

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

setCiphertext

public void setCiphertext(byte[] ciphertext)
                   throws EncryptionException
Set the raw ciphertext.

Parameters:
ciphertext - The raw ciphertext.
Throws:
EncryptionException - Thrown if the MAC has already been computed via computeAndStoreMAC(SecretKey).

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)

getKDF_PRF

public KeyDerivationFunction.PRF_ALGORITHMS getKDF_PRF()

setKDF_PRF

public void setKDF_PRF(int prfSelection)

getEncryptionTimestamp

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


getSerialVersionUID

public static long getSerialVersionUID()
Deprecated. Use CipherText.cipherTextVersion instead. Will disappear as of ESAPI 2.1.

Used in supporting CipherText serialization.


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 http://www.artima.com/lejava/articles/equality.html for full explanation.


getKDFInfo

public int getKDFInfo()
Based on the KDF version and the selected MAC algorithm for the KDF PRF, calculate the 32-bit quantity representing these.

Returns:
A 4-byte (octet) quantity representing the KDF version and the MAC algorithm used for the KDF's Pseudo-Random Function.
See Also:
Format of portable serialization of org.owasp.esapi.crypto.CipherText object (pg 2)


Copyright © 2011 The Open Web Application Security Project (OWASP). All Rights Reserved.