public class PbeWithMD5AndDES_CBC extends DES
The pbeWithMD5AndDES-CBC (password based MD5 with DES-CBC) key-encryption algorithm is used to encrypt a given message (octet string) with the DES algorithm in CBC mode using a secret key which is derived from a password with the MD5 message-digest algorithm. The output of the algorithm also is an octet-string. PKCS#5 alternatively suggests the MD2 message digest algorithm to be combined with the DES-CBC algorithm for encrypting an octet string with a secret key obtained from a password. The general method described in PKCS#5 is intended to 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 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 PbeWithMD5AndDES_CBC algorithm
and encoded as PKCS#8 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.pbeWithMD5AndDES_CBC, null);
RSAPrivateKey rsa_priv_key = (RSAPrivateKey) epki.decrypt("password");
You may also use the PbeWithMD5AndDES_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 need a
PBEKey
(created from some password, which
is recommended by PKCS#5 to consist of printable ASCII characters) and
PBEParameterSpec
(created from
salt and iteration count) for properly initializing the cipher, for instance
(do not forget to include exception handling!):
Random random = new Random(); // salt, 8 bytes long byte[] salt = new byte[8]; random.nextBytes(salt); // iteration count int count = 1; // PBE parameters PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count); // PBEKey from password PBEKey pbeKey = new PBEKey("password"); Cipher pbeCipher = Cipher.getInstance("PbeWithMD5AndDES_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("PbeWithMD5AndDES_CBC"); // initialize for decryption pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec); // decrypt cipher data byte[] plain_data = pbeCipher.doFinal(cipherdata);
PrivateKeyInfo
,
EncryptedPrivateKeyInfo
,
DES
,
PBEKey
,
PBEParameterSpec
,
PBEGenParameterSpec
,
PBEParameterGenerator
,
PBEParameters
,
IaikPBEParameterSpec
Modifier and Type | Field and Description |
---|---|
protected java.security.AlgorithmParameters |
params |
Constructor and Description |
---|
PbeWithMD5AndDES_CBC()
Creates a new PbeWithMD5AndDES_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 algorithm's parameters.
|
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
(DES) 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)
Is used by all engineInit methods and initializes the cipher.
|
java.lang.String |
toString()
Returns a string representation of this Cipher.
|
public PbeWithMD5AndDES_CBC() throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException
Cipher.getInstance("PbeWithMD5AndDES_CBC")
is used to get a
PbeWithMD5AndDES_CBC Cipher object. When dealing with PKCS#8
EncryptedPrivateKeyInfo this algorithm is specified by its appertaining
AlgorithmID, e.g.
epki.encrypt("password", AlgorithmID.pbeWithMD5AndDES_CBC, null);
causing a call to iaik.asn1.structure.AlgorithmID.getInstance()
method which in its turn
calls Cipher.getInstance(algorithmID.getName())
for actually
getting an implementation of the the PbeWithMD5AndDES_CBC algorithm,
finally leading to this constructor.java.security.NoSuchAlgorithmException
- if there is no implementation for DES-CBCjavax.crypto.NoSuchPaddingException
- if there is no implementation for PKCS5PaddingAlgorithmID.getInstance()
,
Cipher.getInstance(java.lang.String)
public java.security.AlgorithmParameters engineGetParameters()
null
is returned.protected void initCipher(int opmode, java.security.Key key) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
java.security.InvalidKeyException
java.security.InvalidAlgorithmParameterException
public void engineInit(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException
PBEKey
in "RAW" format. This method
initializes salt with a self-generated random number and iteration count
with 1 as specified in PKCS#5.opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyrandom
- not needed - shall be nulljava.security.InvalidKeyException
- if the key algorithm is not "PBE" or the format is not "RAW"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
PBEKey
in "RAW" format.
params
is of type PBEParameters
, containing a salt value (of 8 byte length) and iteration
count as specified in PKCS#5.opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyparams
- 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"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
PBEKey
in "RAW" format.
params
is of type PBEParameterSpec
, containing a salt value (of 8 byte length) and iteration
count as specified in PKCS#5.opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODEkey
- the password as PBEKeyparamSpec
- 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"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)
public void engineSetPadding(java.lang.String padding)
padding
- the name of the padding schemeCipherSpi.engineSetPadding(java.lang.String)
public void engineSetMode(java.lang.String mode)
mode
- the cipher modeCipherSpi.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