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):
import iaik.pkcs.pkcs8.*;
...
EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(rsa_priv_key);
epki.encrypt("password", AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC, null);
Decrypting goes the reverse way obtaining a PrivateKeyInfo from
the EncryptedPrivateKeyInfo and "extracting" the RSAPrivateKey:
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 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
Cipher.getInstance("PbeWithSHAAnd3_KeyTripleDES_CBC")
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.
epki.encrypt("password", AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC, null);
causing a call to the
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 PKCS5Paddingiaik.asn1.structures,
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.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterExceptionpublic 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.InvalidKeyExceptionpublic 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.CipherSpiin - 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.CipherSpiin - 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.ShoetBufferException - if the buffer size is to shortjavax.crypto.ShortBufferExceptionBufferedCipher.engineDoFinal(byte[], int, int, byte[], int),
Cipher.doFinal(),
Cipher.update(byte[]),
CipherSpi.engineUpdate(byte[], int, int)public int engineGetOutputSize(int inLen)
update or doFinal operation
including any data currently being buffered.engineGetOutputSize in class javax.crypto.CipherSpiinLen - the number of bytes to processCipher.getOutputSize(int),
CipherSpi.engineGetOutputSize(int)public byte[] engineGetIV()
null is returned.engineGetIV in class javax.crypto.CipherSpinull otherwise.Cipher.getIV(),
CipherSpi.engineGetIV()public int getModeBlockSize()
public int engineGetBlockSize()
engineGetBlockSize in class javax.crypto.CipherSpiCipher.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.CipherSpiin - 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.CipherSpiin - 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.Objectprotected byte[] engineWrap(java.security.Key key)
throws javax.crypto.IllegalBlockSizeException,
java.security.InvalidKeyException
engineWrap in class javax.crypto.CipherSpijavax.crypto.IllegalBlockSizeExceptionjava.security.InvalidKeyExceptionprotected java.security.Key engineUnwrap(byte[] wrappedKey,
java.lang.String wrappedKeyAlgorithm,
int wrappedKeyType)
throws java.security.InvalidKeyException,
java.security.NoSuchAlgorithmException
engineUnwrap in class javax.crypto.CipherSpijava.security.InvalidKeyExceptionjava.security.NoSuchAlgorithmException