public class PbeWithSHAAnd3_KeyTripleDES_CBC extends TripleDES
The pbeWithSHAAnd3_KeyTripleDES_CBC key-encryption algorithm is used to encrypt a given message with the TripleDES algorithm in CBC mode using a secret key which is derived from a password with the SHA hash algorithm.
PKCS#12 breaks with the PKCS#5 recommendation suggesting passwords to consist of printable ASCII characters. PKCS #12 creates passwords from BMPStrings with a NULL terminator by encoding every character of the original BMPString in 2 bytes in big-endian format (most-significant byte first).
As an alternative to the PKCS#5 pbeWithMD5AndDES-CBC
and
pbeWithMD2AndDES-CBC
algorithms, the
pbeWithSHAAnd3_KeyTripleDES_CBC
algorithm may be used for
encrypting private keys, as described in PKCS#8.
Suppose you have created a RSAPrivateKey rsa_priv_key
and are
going to protect it with a password according to PKCS#5, (PKCS#12) and
PKCS#8. You therefore will encode a value of type
PrivateKeyInfo
according to PKCS#8 to
represent the private key in an algorithm-independent manner, which
subsequently will be encrypted using the PbeWithSHAAnd3_KeyTripleDES_CBC
algorithm and encoded as PKCS#8 EncryptedPrivateKeyInfo (
EncryptedPrivateKeyInfo
):
Decrypting goes the reverse way obtaining a PrivateKeyInfo from the EncryptedPrivateKeyInfo and "extracting" the RSAPrivateKey:import iaik.pkcs.pkcs8.*; ... EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(rsa_priv_key); epki.encrypt("password", AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC, null);
RSAPrivateKey rsa_priv_key = (RSAPrivateKey) epki.decrypt("password");
You also may use the PbeWithSHAAnd3_KeyTripleDES_CBC algorithm for password
based encrypting some message in the common way by directly using the
Cipher.getInstance
method when not intending to deal with PKCS#8
EncryptedPrivateKeyInfo
. When
doing so, you will have to use PBEKeyBMP
(created from a password, which is treated as a BMPString
according to PKCS#12) and PBEParameterSpec
(created from salt and iteration count) for properly
initializing the cipher; for instance (do not forget to include exception
handling!):
SecureRandom random = ...; // salt byte[] salt = new byte[16]; random.nextBytes(salt); //iteration count int count = 1; // PBE parameters PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count); // PBEKeyBMP from password PBEKeyBMP pbeKey = new PBEKeyBMP("password"); Cipher pbeCipher = Cipher.getInstance("PbeWithSHAAnd3_KeyTripleDES_CBC"); // initialize for encryption pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); // encrypt data byte[] cipher_data = pbeCipher.doFinal(plain_data); // now decrypt pbeCipher = Cipher.getInstance("PbeWithSHAAnd3_KeyTripleDES_CBC"); // initialize for decryption pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec); // decrypt cipher data byte[] decrypted_data = pbeCipher.doFinal(cipherdata);
PrivateKeyInfo
,
EncryptedPrivateKeyInfo
,
TripleDES
,
PBEKeyBMP
,
PBEParameterSpec
,
PBEGenParameterSpec
,
PBEParameterGenerator
,
PBEParameters
,
IaikPBEParameterSpec
Modifier and Type | Field and Description |
---|---|
protected java.security.AlgorithmParameters |
params |
Constructor and Description |
---|
PbeWithSHAAnd3_KeyTripleDES_CBC()
Creates a new PbeWithSHAAnd3_KeyTripleDES_CBC Cipher object.
|
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.
|
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 of the algorithm.
|
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 mode)
This method only overwrites the corresponding method in its superclass and
does nothing.
|
void |
engineSetPadding(java.lang.String padding)
This method only overwrites the corresponding method in its superclass and
does nothing.
|
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.
|
protected void |
initCipher(int opmode,
java.security.Key key,
java.security.SecureRandom random)
Is used by the engineInit methods and initializes the cipher.
|
java.lang.String |
toString()
Returns a string representation of this Cipher.
|
public PbeWithSHAAnd3_KeyTripleDES_CBC() throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException
Usually this constructor is not directly called for using the PbeWithSHAAnd3_KeyTripleDES_CBC algorithm for password-based encrypting some message. Rather
is used to get a PbeWithSHAAnd3_KeyTripleDES_CBC Cipher object. When dealing with PKCS#8 EncryptedPrivateKeyInfo, this algorithm is specified by its appertaining AlgorithmID, e.g.Cipher.getInstance("PbeWithSHAAnd3_KeyTripleDES_CBC")
causing a call to theepki.encrypt("password", AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC, null);
iaik.asn1.structures.AlgorithmID.getInstance()
method which in its turn
calls Cipher.getInstance(algorithmID.getName())
for actually
getting an implementation of the the PbeWithSHAAnd3_KeyTripleDES_CBC
algorithm, finally leading to this constructor.
java.security.NoSuchAlgorithmException
- if there is no implementation for 3DES-CBCjavax.crypto.NoSuchPaddingException
- if there is no implementation for PKCS5PaddingAlgorithmID
,
Cipher.getInstance(java.lang.String)
public java.security.AlgorithmParameters engineGetParameters()
public void engineInit(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyBMPrandom
- not needed - shall be nulljava.security.InvalidKeyException
- if the key algorithm is not "PBE" or the format is not
"RAW_BMP"Cipher.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.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
params
is of type PBEParameters,
created from salt (of 8 byte length) and iteration count as specified in
PKCS#12.opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyBMPparams
- the algorithm parameters of type PBEParametersrandom
- not needed - shall be nulljava.security.InvalidKeyException
- if the key algorithm is not "PBE" or the format is not
"RAW_BMP"java.security.InvalidAlgorithmParameterException
- if the parameter is no instance of PBEParametersCipher.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
params
is of type PBEParameterSpec,
created from salt (of 8 byte length) and iteration count as specified in
PKCS#12.
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyBMPparamSpec
- the algorithm parameters of type PBEParameterSpecrandom
- not needed - shall be nulljava.security.InvalidKeyException
- if the key algorithm is not "PBE" or the format is not
"RAW_BMP"java.security.InvalidAlgorithmParameterException
- if the parameter is no instance of PBEParameterSpecCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
protected void initCipher(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
java.security.InvalidKeyException
java.security.InvalidAlgorithmParameterException
public void engineSetPadding(java.lang.String padding) throws javax.crypto.NoSuchPaddingException
padding
- 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 mode) throws java.security.NoSuchAlgorithmException
mode
- the cipher modejava.security.NoSuchAlgorithmException
- if this cipher mode is not supportedCipherSpi.engineSetMode(java.lang.String)
protected int engineGetKeySize(java.security.Key key) throws java.security.InvalidKeyException
key
- the key to be usedjava.security.InvalidKeyException
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