public final class CipherText
extends java.lang.Object
implements java.io.Serializable
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
PlainText,
Encryptor,
Serialized Form| Modifier and Type | Class and Description |
|---|---|
private static class |
CipherText.CipherTextFlags |
| Modifier and Type | Field and Description |
|---|---|
private java.util.EnumSet<CipherText.CipherTextFlags> |
allCtFlags |
private CipherSpec |
cipherSpec_ |
static int |
cipherTextVersion |
private long |
encryption_timestamp_ |
private java.util.EnumSet<CipherText.CipherTextFlags> |
fromCipherSpec |
private int |
kdfPrfSelection_ |
private int |
kdfVersion_ |
private static Logger |
logger |
private java.util.EnumSet<CipherText.CipherTextFlags> |
progress |
private byte[] |
raw_ciphertext_ |
private byte[] |
separate_mac_ |
private static long |
serialVersionUID |
| Constructor and 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. |
| Modifier and Type | Method and 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.
|
private boolean |
collectedAll()
Return true if we've collected all the required pieces; otherwise false.
|
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. |
private byte[] |
computeMAC(javax.crypto.SecretKey authKey)
Compute a MAC, but do not store it.
|
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() |
private boolean |
isCollected(CipherText.CipherTextFlags flag)
Check if we've collected a specific flag type.
|
(package private) int |
kdfPRFAsInt() |
private boolean |
macComputed()
Return true if the MAC has already been computed (i.e., not null).
|
private void |
received(CipherText.CipherTextFlags flag)
Add the flag to the set of what we've already collected.
|
private void |
received(java.util.EnumSet<CipherText.CipherTextFlags> ctSet)
Add all the flags from the specified set to that we've collected so far.
|
boolean |
requiresIV()
Return true if the cipher mode used requires an IV.
|
void |
setCiphertext(byte[] ciphertext)
Set the raw ciphertext.
|
private void |
setEncryptionTimestamp()
Set the encryption timestamp to the current system time as determined by
System.currentTimeMillis(), but only if it has not been previously
set. |
(package private) void |
setEncryptionTimestamp(long timestamp)
Set the encryption timestamp to the time stamp specified by the parameter.
|
void |
setIVandCiphertext(byte[] iv,
byte[] ciphertext)
Set the IV and raw ciphertext.
|
void |
setKDF_PRF(int prfSelection) |
void |
setKDFVersion(int vers) |
(package private) void |
storeSeparateMAC(byte[] macValue)
Same as
computeAndStoreMAC(SecretKey) but this is only used by
CipherTextSerializeer. |
java.lang.String |
toString()
More useful
toString() method. |
boolean |
validateMAC(javax.crypto.SecretKey authKey)
Validate the message authentication code (MAC) associated with the ciphertext.
|
public static final int cipherTextVersion
private static final long serialVersionUID
private static final Logger logger
private CipherSpec cipherSpec_
private byte[] raw_ciphertext_
private byte[] separate_mac_
private long encryption_timestamp_
private int kdfVersion_
private int kdfPrfSelection_
private final java.util.EnumSet<CipherText.CipherTextFlags> allCtFlags
private final java.util.EnumSet<CipherText.CipherTextFlags> fromCipherSpec
private java.util.EnumSet<CipherText.CipherTextFlags> progress
public CipherText()
public CipherText(CipherSpec cipherSpec)
CipherSpec object. Still needs to have
setCiphertext(byte[]) or setIVandCiphertext(byte[], byte[])
called to be usable.cipherSpec - The cipher specification to use.public CipherText(CipherSpec cipherSpec, byte[] cipherText) throws EncryptionException
CipherSpec object and the raw ciphertext.cipherSpec - The cipher specification to use.cipherText - The raw ciphertext bytes to use.EncryptionException - Thrown if cipherText is null or
empty array.public static CipherText fromPortableSerializedBytes(byte[] bytes) throws EncryptionException
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().bytes - A byte array created via
CipherText.asPortableSerializedByteArray()CipherText object reconstructed from the byte array.EncryptionExceptionasPortableSerializedByteArray()public java.lang.String getCipherTransformation()
The cipher transformation name is usually sufficient to be passed to
Cipher.getInstance(String) to create a
Cipher object to decrypt the ciphertext.
public java.lang.String getCipherAlgorithm()
public int getKeySize()
public int getBlockSize()
public java.lang.String getCipherMode()
public java.lang.String getPaddingScheme()
public byte[] getIV()
null is returned.public boolean requiresIV()
public byte[] getRawCipherText()
public int getRawCipherTextByteLength()
public java.lang.String getBase64EncodedRawCipherText()
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 or are planning on retrieving the IV and storing it somewhere separately
(e.g., a different database column). If you are not using a fixed IV
(which is highly discouraged), you should normally use
getEncodedIVCipherText() instead.
getEncodedIVCipherText()public java.lang.String getEncodedIVCipherText()
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.
getBase64EncodedRawCipherText()public void computeAndStoreMAC(javax.crypto.SecretKey authKey)
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.
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.void storeSeparateMAC(byte[] macValue)
computeAndStoreMAC(SecretKey) but this is only used by
CipherTextSerializeer. (Has package level access.)public boolean validateMAC(javax.crypto.SecretKey authKey)
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.public byte[] asPortableSerializedByteArray()
throws EncryptionException
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.EncryptionExceptionpublic void setCiphertext(byte[] ciphertext)
throws EncryptionException
ciphertext - The raw ciphertext.EncryptionException - Thrown if the MAC has already been computed
via computeAndStoreMAC(SecretKey).public void setIVandCiphertext(byte[] iv,
byte[] ciphertext)
throws EncryptionException
iv - The initialization vector.ciphertext - The raw ciphertext.EncryptionExceptionpublic int getKDFVersion()
public void setKDFVersion(int vers)
public KeyDerivationFunction.PRF_ALGORITHMS getKDF_PRF()
int kdfPRFAsInt()
public void setKDF_PRF(int prfSelection)
public long getEncryptionTimestamp()
private void setEncryptionTimestamp()
System.currentTimeMillis(), but only if it has not been previously
set. That is, this method ony has an effect the first time that it is
called for this object.void setEncryptionTimestamp(long timestamp)
This method is intended for use only by CipherTextSerializer.
timestamp - The time in milliseconds since epoch time (midnight,
January 1, 1970 GMT).public static long getSerialVersionUID()
CipherText.cipherTextVersion instead. Will
disappear as of ESAPI 2.1.CipherText serialization.public byte[] getSeparateMAC()
computeAndStoreMAC(SecretKey authKey) method.null if one is not used.public java.lang.String toString()
toString() method.toString in class java.lang.Objectpublic boolean equals(java.lang.Object other)
equals in class java.lang.Objectpublic int hashCode()
hashCode in class java.lang.Objectprotected boolean canEqual(java.lang.Object other)
See http://www.artima.com/lejava/articles/equality.html
for full explanation.
private byte[] computeMAC(javax.crypto.SecretKey authKey)
HMAC-SHA1(nonce, IV + plaintext)
ciphertext - The ciphertext value for which the MAC is computed.private boolean macComputed()
private boolean collectedAll()
private boolean isCollected(CipherText.CipherTextFlags flag)
flag - The flag type; e.g., CipherTextFlags.INITVECTOR, etc.private void received(CipherText.CipherTextFlags flag)
flag - The flag type to be added; e.g., CipherTextFlags.INITVECTOR.private void received(java.util.EnumSet<CipherText.CipherTextFlags> ctSet)
ctSet - A EnumSet<CipherTextFlags> containing all the flags
we wish to add.public int getKDFInfo()