public class PBES2Cipher
extends javax.crypto.CipherSpi
The PBES2 password based encryption scheme needs the following two parameter sets:
PBES2ParameterSpec
to init the
Cipher with the PBKDF2 key derivation parameters (salt value, iteration count,
length of the to-be-derived key, prf) and the encryption scheme
(and maybe any associated encryption parameters) to be used
PBKDF2ParameterSpec
to init the
Cipher with the PBKDF2 key derivation parameters (salt value, iteration count, length of the
to-be-derived key and prf)
PBEParameterSpec
to init the
Cipher with salt value and iteration count parameters for PBKDF2 key derivation
IvParameterSpec
to init the
Cipher with an initialization vector to be used by the encryption scheme
(if an iv is the only parameter required by the encryption scheme, e.g. AES in CBC mode)
PBES2ParameterSpec
, where all
parameters can be explicitly specified, initialization with any other parameter specification
uses the default settings for those parameters that are not explicitly specified.
Alternatively you may use one of the following pre-defined PBES2 Ciphers with fixed pseudorandom function and encryption scheme:
PBES2WithHmacSHA1AndAES
:
Cipher.getInstance("PBES2WithHmacSHA1AndAES", "IAIK");
PBES2WithHmacSHA256AndAES
:
Cipher.getInstance("PBES2WithHmacSHA256AndAES", "IAIK");
PBES2WithHmacSHA384AndAES192
:
Cipher.getInstance("PBES2WithHmacSHA384AndAES192", "IAIK");
PBES2WithHmacSHA512AndAES256
:
Cipher.getInstance("PBES2WithHmacSHA512AndAES256", "IAIK");
PBES2WithHmacSHA1AndDESede
:
Cipher.getInstance("PBES2WithHmacSHA1AndDESede", "IAIK");
Although you can use any of the parameter specifications from above when initializing a
PBES2 Cipher for encryption you MUST use a PBES2ParameterSpec
for
initializing the PBES2 Cipher for decryption because the Cipher must know the salt value and
cipher parameters (e.g. iv value) that have been used for encryption. The following sample shows
a typical use case where a PBES2WithHmacSHA256AndAES
Cipher is initialized without parameters for encryption (using HMAC/SHA256 as prf and AES128-CBC
for data encryption) and then is initialized for decryption with the parameters generated by the Cipher:
char[] password = ...; // create a PBEKeySpec from our password PBEKeySpec keySpec = new PBEKeySpec(password); // use the "PKCS#5" SecretKeyFactory to convert the password SecretKeyFactory kf = SecretKeyFactory.getInstance("PKCS#5", "IAIK"); // create an appropriate PbeKey PBEKey pbeKey = (PBEKey)kf.generateSecret(keySpec); // get the cipher Cipher c = Cipher.getInstance("PBES2WithHmacSHA256AndAES", "IAIK"); // initialize it with the PBEKey c.init(Cipher.ENCRYPT_MODE, pbeKey); // encrypt the data byte[] encrypted = c.doFinal(data); // get the Cipher params (PBES2Parameters) AlgorithmParameters params = c.getParameters(); // now decrypt c = Cipher.getInstance("PBES2WithHmacSHA256AndAES", "IAIK"); // initialize the cipher again for decrypting and use // the generated AlgorithmParameters with the same key c.init(Cipher.DECRYPT_MODE, pbeKey, params, null); // decrypt the data byte[] decrypted = c.doFinal(encrypted);If you want to use a different pseudo random function and/or encryption scheme than those provided by the default PBES2Cipher set, you must use the general PBES2 Cipher and initialize it with a
PBES2ParameterSpec
.
The following example uses the same prf (HMAC/SHA256) and encryption scheme (AES128-CBC)
as the example above but uses a general PBES2 Cipher and intializes it with PBES2 parameters:
char[] password = ...; // create a PBEKeySpec from our password PBEKeySpec keySpec = new PBEKeySpec(password); // use the "PKCS#5" SecretKeyFactory to convert the password SecretKeyFactory kf = SecretKeyFactory.getInstance("PKCS#5", "IAIK"); // create an appropriate PbeKey PBEKey pbeKey = (PBEKey)kf.generateSecret(keySpec); // specify the PBES2 parameters int iterationCount = 2000; byte[] salt = new byte[32]; SecureRandom secRandom = SecRandom.getDefault(); secRandom.nextBytes(salt); AlgorithmID prf = (AlgorithmID)AlgorithmID.hMAC_SHA256.clone(); AlgorithmID encryptionScheme = (AlgorithmID)AlgorithmID.aes128_CBC.clone(); int aesKeyLength = 16; // create the PBES2 parameters PBES2ParameterSpec pbes2ParameterSpec = new PBES2ParameterSpec(salt, iterationCount, aesKeyLength, encryptionScheme); pbes2ParameterSpec.setPrf(prf); // get the cipher Cipher c = Cipher.getInstance("PBES2", "IAIK"); // initialize it with PBEKey and PBES parameters c.init(Cipher.ENCRYPT_MODE, pbeKey, pbes2ParameterSpec); // encrypt the data byte[] encrypted = c.doFinal(data); // get the Cipher params (PBES2Parameters) AlgorithmParameters params = c.getParameters(); // now decrypt c = Cipher.getInstance("PBES2", "IAIK"); // initialize the cipher again for decrypting c.init(Cipher.DECRYPT_MODE, pbeKey, params, null); // decrypt the data byte[] decrypted = c.doFinal(encrypted);
Cipher
,
PBES2Cipher.PBES2WithHmacSHA1AndAES
,
PBES2Cipher.PBES2WithHmacSHA256AndAES
,
PBES2Cipher.PBES2WithHmacSHA384AndAES192
,
PBES2Cipher.PBES2WithHmacSHA512AndAES256
,
PBES2Cipher.PBES2WithHmacSHA1AndDESede
,
PBES2ParameterSpec
,
PBKDF2ParameterSpec
,
PBEParameterSpec
,
IvParameterSpec
Modifier and Type | Class and Description |
---|---|
static class |
PBES2Cipher.PBES2WithHmacSHA1AndAES
PBES2 Cipher using HmacSHA1 as pseudo random function and AES128-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA1AndAES256
PBES2 Cipher using HmacSHA1 as pseudo random function and AES256-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA1AndDESede
PBES2 Cipher using HmacSHA1 as pseudo random function and DESede-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA224AndAES
PBES2 Cipher using HmacSHA224 as pseudo random function and AES128-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA224AndAES256
PBES2 Cipher using HmacSHA224 as pseudo random function and AES256-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA256AndAES
PBES2 Cipher using HmacSHA256 as pseudo random function and AES128-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA256AndAES256
PBES2 Cipher using HmacSHA256 as pseudo random function and AES256-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA384AndAES
PBES2 Cipher using HmacSHA384 as pseudo random function and AES128-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA384AndAES192
PBES2 Cipher using HmacSHA384 as pseudo random function and AES192-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA384AndAES256
PBES2 Cipher using HmacSHA384 as pseudo random function and AES256-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA512AndAES
PBES2 Cipher using HmacSHA512 as pseudo random function and AES128-CBC as Cipher.
|
static class |
PBES2Cipher.PBES2WithHmacSHA512AndAES256
PBES2 Cipher using HmacSHA512 as pseudo random function and AES256-CBC as Cipher.
|
Constructor and Description |
---|
PBES2Cipher()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
byte[] |
engineDoFinal(byte[] in,
int inOff,
int inLen)
Returns the result of the last step of a multi-step en/decryption operation
or the result of a single-step en/decryption operation by processing the
given input data and any remaining buffered data.
|
int |
engineDoFinal(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
Performs the last step of a multi-step en/decryption operation or a
single-step en/decryption operation by processing the given input data and
any remaining buffered data.
|
int |
engineGetBlockSize()
Returns the block size corresponding to this cipher.
|
byte[] |
engineGetIV()
Returns a byte array containing the initialization vector (IV).
|
protected int |
engineGetKeySize(java.security.Key key)
Gets the key size of the derived key.
|
int |
engineGetOutputSize(int inLen)
Returns the output buffer size necessary for capturing the data resulting
from the next
update or doFinal operation
including any data currently being buffered. |
java.security.AlgorithmParameters |
engineGetParameters()
Returns the parameters used by this Cipher.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.spec.AlgorithmParameterSpec paramSpec,
java.security.SecureRandom random)
Initializes this cipher for encryption or decryption.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.AlgorithmParameters params,
java.security.SecureRandom random)
Initializes this cipher for encryption or decryption.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.SecureRandom random)
Initializes this cipher for encryption or decryption.
|
void |
engineSetMode(java.lang.String cipherMode)
Sets the mode of this cipher.
|
void |
engineSetPadding(java.lang.String paddingName)
Sets the padding scheme of this cipher.
|
protected java.security.Key |
engineUnwrap(byte[] wrappedKey,
java.lang.String wrappedKeyAlgorithm,
int wrappedKeyType) |
byte[] |
engineUpdate(byte[] in,
int inOff,
int inLen)
This method is used to encrypt or decrypt chunks of data of any length.
|
int |
engineUpdate(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
This method is used to encrypt or decrypt chunks of data of any length.
|
protected void |
engineUpdateAAD(byte[] src,
int offset,
int len) |
protected byte[] |
engineWrap(java.security.Key key) |
int |
getModeBlockSize()
Returns the block size corresponding to the actual cipher mode.
|
java.lang.String |
toString()
Returns a string representation of this Cipher.
|
public void engineInit(int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
PBEKey
in "RAW" format.
When initializing the Cipher for encryption any of the following
parameters may be used:
PBES2Parameters
to init the
Cipher with the PBKDF2 key derivation parameters (salt value, iteration count,
length of the to-be-derived key, prf) and the encryption scheme
(and maybe any associated encryption parameters) to be used
PBKDF2Parameters
to init the
Cipher with the PBKDF2 key derivation parameters salt value, iteration count, length of the
to-be-derived key and prf
PBEParameters
to init the
Cipher with salt value and iteration count parameters for PBKDF2 key derivation
IvParameters
to init the
Cipher with an initialization vector to be used by the encryption scheme
(if an iv is the only parameter required by the encryption scheme, e.g. AES in CBC mode)
When initializing the Cipher for decryption PBES2Parameters
must be used!
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyparams
- the algorithm parametersrandom
- the random number generatorjava.security.InvalidKeyException
- if the key algorithm is not "PKCS#5" or "PBE" or the format is not "RAW"java.security.InvalidAlgorithmParameterException
- if the parameters are not applicable for this CipherCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public void engineInit(int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec paramSpec, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
PBEKey
in "RAW" format.
When initializing the Cipher for encryption paramSpec
any of the following
parameters can be used:
PBES2ParameterSpec
to init the
Cipher with the PBKDF2 key derivation parameters (salt value, iteration count,
length of the to-be-derived key, prf) and the encryption scheme
(and maybe any associated encryption parameters) to be used
PBKDF2ParameterSpec
to init the
Cipher with the PBKDF2 key derivation parameters salt value, iteration count, length of the
to-be-derived key and prf
PBEParameterSpec
to init the
Cipher with salt value and iteration count parameters for PBKDF2 key derivation
IvParameterSpec
to init the
Cipher with an initialization vector to be used by the encryption scheme
(if an iv is the only parameter required by the encryption scheme, e.g. AES in CBC mode)
PBES2Parameters
must be used!opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyparamSpec
- the algorithm parametersrandom
- the random number generatorjava.security.InvalidKeyException
- if the key algorithm is not "PKCS#5" or "PBE" or the format is not "RAW"java.security.InvalidAlgorithmParameterException
- if the parameters are not applicable for this CipherCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public void engineInit(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException
PBEKey
in "RAW" format. This method
initializes the Cipher with default parameters.opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyrandom
- the
the random number generatorjava.security.InvalidKeyException
- if the key algorithm is not "PKCS#5" or "PBE" or the format is not "RAW"Cipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public java.security.AlgorithmParameters engineGetParameters()
PBES2Parameters
and may have been
specified during intialization or may have been generated by this Cipher.PBES2Parameters
protected int engineGetKeySize(java.security.Key key) throws java.security.InvalidKeyException
key
- the Key; ignoredjava.security.InvalidKeyException
public void engineSetPadding(java.lang.String paddingName) throws javax.crypto.NoSuchPaddingException
paddingName
- the name of the padding schemejavax.crypto.NoSuchPaddingException
- if this padding scheme is not supportedCipherSpi.engineSetPadding(java.lang.String)
public void engineSetMode(java.lang.String cipherMode) throws java.security.NoSuchAlgorithmException
cipherMode
- the cipher modejava.security.NoSuchAlgorithmException
- if this cipher mode is not supportedCipherSpi.engineSetMode(java.lang.String)
public byte[] engineUpdate(byte[] in, int inOff, int inLen)
doFinal()
method. This
method will automatically allocate an output buffer of the right size.engineUpdate
in class javax.crypto.CipherSpi
in
- the input data.inOff
- the offset indicating where the subarray starts in the
in
array.inLen
- the length of the subarray.BufferedCipher.engineDoFinal(byte[], int, int, byte[], int)
,
Cipher.doFinal()
,
Cipher.update(byte[])
,
CipherSpi.engineUpdate(byte[], int, int)
public int engineUpdate(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws javax.crypto.ShortBufferException
doFinal()
method.engineUpdate
in class javax.crypto.CipherSpi
in
- the input data.inOff
- the offset indicating where the subarray starts in the
in
array.inLen
- the length of the subarray.out
- the output buffer.outOff
- the offset indicating where to start writing the result into the
output buffer.out
array.javax.crypto.ShortBufferException
- if the buffer size is to shortBufferedCipher.engineDoFinal(byte[], int, int, byte[], int)
,
Cipher.doFinal()
,
Cipher.update(byte[])
,
CipherSpi.engineUpdate(byte[], int, int)
protected void engineUpdateAAD(byte[] src, int offset, int len)
engineUpdateAAD
in class javax.crypto.CipherSpi
public int engineGetOutputSize(int inLen)
update
or doFinal
operation
including any data currently being buffered.engineGetOutputSize
in class javax.crypto.CipherSpi
inLen
- the number of bytes to processCipher.getOutputSize(int)
,
CipherSpi.engineGetOutputSize(int)
public byte[] engineGetIV()
null
is returned.engineGetIV
in class javax.crypto.CipherSpi
null
otherwise.Cipher.getIV()
,
CipherSpi.engineGetIV()
public int getModeBlockSize()
public int engineGetBlockSize()
engineGetBlockSize
in class javax.crypto.CipherSpi
Cipher.getBlockSize()
,
CipherSpi.engineGetBlockSize()
public int engineDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws javax.crypto.ShortBufferException, javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted, including any buffered bytes of a previous
update
operation. If necessary, padding is performed. The
result is stored in the given output byte array, beginning at
outputOffset
. The number of bytes stored in this byte array
are returned.
engineDoFinal
in class javax.crypto.CipherSpi
in
- the byte array holding the data to be processedinOff
- the offset indicating the start position within the input byte
arrayinLen
- the number of bytes to be processedout
- the byte array for holding the resultoutOff
- the offset indicating the start position within the output byte
array to which the en/decrypted data is writtenjavax.crypto.ShortBufferException
- if the given output buffer is too small for holding the resultjavax.crypto.IllegalBlockSizeException
- if the total length of the processed data is not a multiple of
the block size for a (no padding performing) block cipherjavax.crypto.BadPaddingException
- if the decrypted data is not bounded by the proper padding
bytes after data decryption including (un)paddingCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
public byte[] engineDoFinal(byte[] in, int inOff, int inLen) throws javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted, including any buffered bytes of a previous
update
operation. If necessary, padding is performed. The
result is returned as a output byte array.
engineDoFinal
in class javax.crypto.CipherSpi
in
- the byte array holding the data to be processedinOff
- the offset indicating the start position within the input byte
arrayinLen
- the number of bytes to be processedjavax.crypto.IllegalBlockSizeException
- if the total length of the processed data is not a multiple of
the block size for a (no padding performing) block cipherjavax.crypto.BadPaddingException
- if the decrypted data is not bounded by the proper padding
bytes after data decryption including (un)paddingCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
public java.lang.String toString()
toString
in class java.lang.Object
protected byte[] engineWrap(java.security.Key key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException
engineWrap
in class javax.crypto.CipherSpi
javax.crypto.IllegalBlockSizeException
java.security.InvalidKeyException
protected java.security.Key engineUnwrap(byte[] wrappedKey, java.lang.String wrappedKeyAlgorithm, int wrappedKeyType) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException
engineUnwrap
in class javax.crypto.CipherSpi
java.security.InvalidKeyException
java.security.NoSuchAlgorithmException