public class PbeWithSHAAnd40BitRC2_CBC extends RC2
The PbeWithSHAAnd40BitRC2_CBC key-encryption algorithm is used to encrypt a given message with the RC2 algorithm in CBC mode using a 40Bit secret key which is derived from a password with the SHA hash algorithm as described in PKCS#12.
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
pbeWithSHAAnd40BitRC2_CBC algorithm maybe 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 PbeWithSHAAnd40BitRC2_CBC algorithm
and encoded as PKCS#8 EncryptedPrivateKeyInfo:
import iaik.pkcs.pkcs8.*;
...
EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(rsa_priv_key);
epki.encrypt("password", AlgorithmID.pbeWithSHAAnd40BitRC2_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 PbeWithSHAAnd40BitRC2_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 use PBEKeyBMP
(created from some password, which is treated as 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!):
Random random = new 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("PbeWithSHAAnd40BitRC2_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("PbeWithSHAAnd40BitRC2_CBC");
// initialize for decryption
pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);
// decrypt cipher data
byte[] decrypted_data = pbeCipher.doFinal(cipherdata);
PrivateKeyInfo,
EncryptedPrivateKeyInfo,
RC2,
PBEKeyBMP,
PBEParameterSpec,
PBEGenParameterSpec,
PBEParameterGenerator,
PBEParameters,
IaikPBEParameterSpec| Modifier and Type | Field and Description |
|---|---|
protected java.security.AlgorithmParameters |
params
Contains the parameters the cipher is initialized with
|
| Constructor and Description |
|---|
PbeWithSHAAnd40BitRC2_CBC()
Creates a new PbeWithSHAAnd40BitRC2_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()
This method 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 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)
This method is used by the engineInit methods and initializes the cipher.
|
java.lang.String |
toString()
Returns a string representation of this Cipher.
|
protected java.security.AlgorithmParameters params
public PbeWithSHAAnd40BitRC2_CBC()
throws java.security.NoSuchAlgorithmException,
javax.crypto.NoSuchPaddingException
Usually this constructor is not directly called for using the PbeWithSHAAnd40BitRC2_CBC algorithm for password-based encrypting some message. Rather
Cipher.getInstance("PbeWithSHAAnd40BitRC2_CBC")
is used to get a PbeWithSHAAnd40BitRC2_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 getInstance method of the
iaik.asn1.structures.AlgorithmID class which in its turn calls
Cipher.getInstance(algorithmID.getName()) for actually getting
an implementation of the the PbeWithSHAAnd40BitRC2_CBC algorithm, finally
leading to this constructor.
java.security.NoSuchAlgorithmException - if there is no implementation for RC2-CBCjavax.crypto.NoSuchPaddingException - if there is no implementation for PKCS5Paddingpublic java.security.AlgorithmParameters engineGetParameters()
null.public void engineInit(int opmode,
java.security.Key key,
java.security.SecureRandom random)
throws java.security.InvalidKeyException
The key must be a PBEKeyBMP in "RAW_BMP" format; you may use a
PBEKeyBMP key. This method
initializes salt (random value of 8 byte length) and iteration count with 1
as specified in PKCS#12.
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
The key must be a PBEKeyBMP in "RAW_BMP" format; you may use a
PBEKeyBMP key. params
has to be of type PBEParameterSpec, created from salt 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
The key must be a PBEKeyBMP in "RAW_BMP" format; you may use a
PBEKeyBMP key. params
has to be of type PBEParameterSpec, created from salt 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