|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--javax.crypto.CipherSpi | +--iaik.security.cipher.BufferedCipher | +--iaik.security.cipher.CMSKeyWrapCipher | +--iaik.security.cipher.RC2KeyWrap
This class implements the CMS RC2 Key Wrap algorithm.
RFC 2630 (Cryptographic Message Syntax) (Section 12.6.2, 12.6.3) specifies the RC2 key wrap algorithm for wrapping RC2 content encryption keys with RC2 key encryption keys when using the KeyAgreeRecipientInfo or KEKRecipientInfo choice for providing recipient specific information when encrypting data using the EnvelopedData type.
Since this class only can be used for wrapping/unwrapping secret content encryption keys
an application only can call methods wrap
and unwrap
of the corresponding Cipher object. Any attempt to call a update
or
doFinal
method will cause a RuntimeException to be thrown.
A CMS key wrap (unwrap) procedure involves two encryption (decryption) operations,
both run in CBC mode.
The first encryption step uses a random IV and the second encryption step uses
a fixed IV of 0x4adda22c79e82105. Correspondingly the first decryption
step uses a fixed IV (0x4adda22c79e82105) and the second decryption step
uses the random IV recovered from the first decryption. When calling an
engineInit
method the supplied parameters only may specify the effective
key length to be used; either immediately
or via RC2ParameterVersion
;
this CMS RC2 key wrap cipher implementation itself takes care for using the right IV
for the right en/decryption step. When calling method getIV
this class
always returns null
; when calling method getParameters
this class returns the RC2ParameterVersion
to be included in the parameters field of the algorithm id.
When creating a new CMS RC2 key wrap Cipher object you only may provide the name of the key wrap cipher ("RC2WrapRC2"). Any cipher mode (always uses CBC) or padding (does the padding itself) specification is ignored.
For example, wrapping a RC2 content encryption key using a RC2 key encryption key typically may be done as follows:
// the content encryption key to be wrapped: SecretKey cek = ...; // the key encryption key to be used: SecretKey kek = ...; // get a RC2 key wrap cipher: Cipher c = Cipher.getInstance("RC2WrapRC2"); // init with the key encryption key c.init(Cipher.WRAP_MODE, kek); // wrap the content encryption key: byte[] wrappedCek = c.wrap(cek); // get the parameters: RC2WrapParameters rc2WrapParameters = (RC2WrapParameters)c.getParameters();For unwrapping the key init the Cipher in unwrap mode:
Cipher c = Cipher.getInstance("RC2WrapRC2"); // init with the key encryption key c.init(Cipher.UNWRAP_MODE, kek, rc2WrapParameters, random); // unwrap the wrapped content encryption key: Key unwrappedCek = c.unwrap(wrappedCek, "RC2", Cipher.SECRET_KEY);
Field Summary | |
protected int |
cipherTextLength
The expected cipher text length, may be required to be checked. |
static byte[] |
CMS_KEY_WRAP_IV
The IV for the last encryption step of CMS key wrap. |
protected Key |
kek
The key encryption key (used for en/decrypting the content encryption key). |
protected byte[] |
keyWrapIV
The IV to be used for the second encryption step. (default 0x4adda22c79e82105) |
protected SecureRandom |
random
The SecureRandom. |
Constructor Summary | |
RC2KeyWrap()
Creates a RC2KeyWrap object. |
Method Summary | |
protected byte[] |
computeLCEKPAD(Key contentEncryptionKey)
Calculates the LCEKPAD value (RFC 2630, Section 12.6.4) from the given content encryption key. |
protected byte[] |
decomposeLCEKPAD(byte[] LCEKPAD)
Decomposes the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK As last step of the RC2 Key UnWrap algorithm described in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek. |
byte[] |
engineDoFinal(byte[] in,
int inOff,
int inLen)
Throws a RuntimeException since not supported by this key wrap cipher. |
int |
engineDoFinal(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
Throws a RuntimeException since not supported by this key wrap cipher. |
int |
engineGetBlockSize()
Returns the block size corresponding to this cipher. |
byte[] |
engineGetIV()
Returns null. |
protected int |
engineGetKeySize(Key key)
New method in JCE 1.2.1 |
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. |
AlgorithmParameters |
engineGetParameters()
Returns the algorithm parameters of this RC2KeyWrap cipher. |
void |
engineInit(int opmode,
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
Initializes this cipher object. |
void |
engineInit(int opmode,
Key key,
AlgorithmParameters params,
SecureRandom random)
Initializes this cipher object. |
protected void |
engineInit(int opmode,
Key key,
byte[] iv,
SecureRandom random)
Internal inits the underlying RC2 cipher for the second en/decryption step. |
void |
engineInit(int opmode,
Key key,
SecureRandom random)
Initializes this cipher object. |
void |
engineSetMode(String mode)
Sets the mode of this cipher to "CBC". |
void |
engineSetPadding(String paddingName)
Sets the padding scheme of this cipher. |
protected Key |
engineUnwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm,
int wrappedKeyType)
Unwraps the given wrapped key to recover the content encryption key. |
byte[] |
engineUpdate(byte[] in,
int inOff,
int inLen)
Throws a RuntimeException since not supported by this key wrap cipher. |
int |
engineUpdate(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
Throws a RuntimeException since not supported by this key wrap cipher. |
protected byte[] |
engineWrap(Key key)
Engine method for key wrapping. |
protected Key |
finishUnWrap(byte[] decryptedCek,
String wrappedKeyAlgorithm,
int wrappedKeyType)
Finishes the unwrapping process by decomposing the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK As last step of the RC2 Key UnWrap algorithm described in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek. |
int |
getModeBlockSize()
Returns the block size corresponding to the actual cipher mode. |
protected SecureRandom |
getRandom()
Gets the SecureRandom. |
protected byte[] |
prepareWrap(Key contentEncryptionKey)
Prepares the given content encryption RC2 key for being wrapped. |
String |
toString()
Returns a string representation of this Cipher. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
protected Key kek
protected int cipherTextLength
protected SecureRandom random
protected byte[] keyWrapIV
public static final byte[] CMS_KEY_WRAP_IV
IV = 0x4adda22c79e82105.
Constructor Detail |
public RC2KeyWrap()
Cipher.getInstance
factory
methods instead, e.g.:
Cipher RC2KeyWrap = Cipher.getInstance("RC2WrapRC2");Since the RC2KeyWrap cipher only runs in CBC mode and itself takes care for padding, any mode or padding specification as part of the transformation string supplied when creating the Cipher object is ignored.
Method Detail |
public void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException
Any parameters to be set have to be supplied as instances of RC2WrapParameterSpec
giving
the number of effective key bits to be used.
If the cipher has to be initialized for key wrap, a random IV is used.
If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.
engineInit
in class iaik.security.cipher.BufferedCipher
opmode
- the operation mode for which this cipher is used
(WRAP_MODE or UNWRAP_MODE)key
- the key encryption key to be usedparams
- the algorithm parametersrandom
- the random seedInvalidKeyException
- if the given key cannot be used for initializing this cipherInvalidAlgorithmParameterException
- if the given algorithm parameters don´t match to this cipherpublic void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException
Any parameters to be set have to be supplied as instances of RC2WrapParameters
giving the
RC2ParameterVersion from which to derive the number of effective key bits to be
used.
If the cipher has to be initialized for key wrap, a random IV is used.
If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.
engineInit
in class iaik.security.cipher.BufferedCipher
opmode
- the operation mode for which this cipher is used
(WRAP_MODE or UNWRAP_MODE)key
- the key encryption keyparams
- the algorithm parametersrandom
- the random seedInvalidKeyException
- if the given key cannot be used for initializing this cipherInvalidAlgorithmParameterException
- if the given algorithm parameters don´t match to this cipherprotected void engineInit(int opmode, Key key, byte[] iv, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException
A CMS key wrap (unwrap) procedure involves two encryption (decryption) operations, both run in CBC mode. The first encryption step uses a random IV and the second encryption step uses a fixed IV of default 0x4adda22c79e82105. Correspondingly the first decryption step uses a fixed IV (default 0x4adda22c79e82105) and the second decryption step uses the random IV recovered from the first decryption. This method is called during the wrapping/unwrapping to init the underlying RC2 cipher for the second en/decryption step. The given iv is used to be included in RC2 parameters for initializing the underlying cipher.
engineInit
in class iaik.security.cipher.CMSKeyWrapCipher
opmode
- the operation modekey
- the key encryption keyiv
- the initialization vector, either fixed (for second encryption step)
or recovered random (for second decryption step)random
- the random seedInvalidKeyException
- if something is wrong with the keyInvalidAlgorithmParameterException
- if an error occurs when creating the
parameters from the ivpublic AlgorithmParameters engineGetParameters()
The parameters are returned as RC2WrapParameters
giving the RC2ParameterVersion from which the number of
effective key bits may be derived:
RC2wrapParameter :: RC2ParameterVersion RC2ParameterVersion ::= INTEGERThe RC2 effective-key-bits (key size) greater than 32 and less than 256 is encoded in the RC2ParameterVersion. For the effective-key- bits of 40, 64, and 128, the rc2ParameterVersion values are 160, 120, and 58 respectively. These values are not simply the RC2 key length.
engineGetParameters
in class iaik.security.cipher.CMSKeyWrapCipher
iaik.security.cipher.CMSKeyWrapCipher
protected byte[] prepareWrap(Key contentEncryptionKey) throws InvalidKeyException
This method calculates the LCEKPAD value (RFC 2630, Section 12.6.4) from the given content encryption key.
As first step of the RC2 Key Wrap algorithm described in RFC2630, the content-encryption key is concatenated with its length and padded to a multiple of 8, if required:
prepareWrap
in class iaik.security.cipher.CMSKeyWrapCipher
contentEncryptionKey
- the content encryption key for which to calculate the
LCEKPAD valueprotected Key finishUnWrap(byte[] decryptedCek, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException
As last step of the RC2 Key UnWrap algorithm described in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek.
finishUnWrap
in class iaik.security.cipher.CMSKeyWrapCipher
LCEKPAD
- the LCEKPAD value (LENGTH || CEK || PAD)InvalidKeyException
- if the key cannot be unwrapped because
the PAD value of the LCEKPAD is invalid
(has a length not shorter than 8public void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException
If the cipher has to be initialized for key wrap, a random IV is used. If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.
engineInit
in class iaik.security.cipher.BufferedCipher
opmode
- the operation mode for which this cipher is used
(WRAP_MODE or UNWRAP_MODE)key
- the key encryption key to be usedrandom
- the random seedInvalidKeyException
- if the given key cannot be used for
initializing this cipherpublic void engineSetPadding(String paddingName) throws NoSuchPaddingException
This method only overrides engineSetPadding
for not allowing
an application to request a specific padding scheme (this key wrap cipher
itself takes care for padding).
engineSetPadding
in class iaik.security.cipher.BufferedCipher
paddingName
- the name of the padding scheme; ignoredNoSuchPaddingException
- if this padding scheme is not supportedpublic void engineSetMode(String mode) throws NoSuchAlgorithmException
This method only overrides engineSetMode
for not allowing
an application to request a specific cipher mode (this key wrap cipher
always uses "CBC").
engineSetMode
in class iaik.security.cipher.BufferedCipher
mode
- the cipher modeNoSuchAlgorithmException
- if this cipher mode is not supportedpublic byte[] engineUpdate(byte[] in, int inOff, int inLen)
wrap
/unwrap
for wrapping/unwrapping a key.engineUpdate
in class iaik.security.cipher.BufferedCipher
iaik.security.cipher.BufferedCipher
in
- the input data.inOff
- the offset indicating where the subarray starts in the
in
array.inLen
- the length of the subarray.isFinal
- true, if this is the last call to updateBufferedCipher.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 ShortBufferException
wrap
/unwrap
for wrapping/unwrapping a key.engineUpdate
in class iaik.security.cipher.BufferedCipher
iaik.security.cipher.BufferedCipher
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.ShoetBufferException
- if the buffer size is to shortBufferedCipher.engineDoFinal(byte[], int, int, byte[], int)
,
Cipher.doFinal()
,
Cipher.update(byte[])
,
CipherSpi.engineUpdate(byte[], int, int)
public int engineDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
wrap
/unwrap
for wrapping/unwrapping a key.engineDoFinal
in class iaik.security.cipher.BufferedCipher
iaik.security.cipher.BufferedCipher
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 writtenShortBufferException
- if the given output buffer is too small for holding the resultIllegalBlockSizeException
- if the total length of the processed data is not a multiple of the
block size for a (no padding performing) block cipherBadPaddingException
- 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 IllegalBlockSizeException, BadPaddingException
wrap
/unwrap
for wrapping/unwrapping a key.engineDoFinal
in class iaik.security.cipher.BufferedCipher
iaik.security.cipher.BufferedCipher
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 processedIllegalBlockSizeException
- if the total length of the processed data is not a multiple of the block size for a
(no padding performing) block cipherBadPaddingException
- 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[] engineGetIV()
engineGetIV
in class iaik.security.cipher.BufferedCipher
public String toString()
toString
in class iaik.security.cipher.BufferedCipher
protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException
CipherSpi
engineWrap
in class iaik.security.cipher.BufferedCipher
protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException
This method implements the core operations common to the Triple-DES and RC2 Key
Wrap algorithms of RFC 2630, in particular the equivalent steps 1 to 7 of
Triple-DES Key Unwrap (section 12.6.3 of RFC 2630) respectively steps 1 to 7
of RC2 Key Unwrap (section 12.6.5 of RFC 2630).
Any key wrap algorithm specific operations required to finish the unwrap
procedure may be done by implementing the abstract method finishUnWrap
for the specific key wrap
algorithm in mind. Triple-DES Key wrap, for instance,
requires the content encryption key to be (odd) parity adjusted before being
wrapped. Triple-DES Key Wrap is implemented by class TripleDESKeyWrap
which implements
method finishUnWrap
to check odd
parity at the end of the unwrapping procedure.
engineUnwrap
in class iaik.security.cipher.BufferedCipher
wrappedKey
- the wrapped content encryption key to be unwrappedwrappedKeyAlgorithm
- the content encryption key algorithmwrappedKeyType
- the key type, Cipher.SECRET_KEYInvalidKeyException
- if an error occurs while unwrapping the keyNoSuchAlgorithmException
- if the algorithm used is not supported
by the installed providersprotected SecureRandom getRandom()
If no SecureRandom has been set, a new one is created.
protected byte[] computeLCEKPAD(Key contentEncryptionKey)
As first step of the RC2 Key Wrap algorithm described in RFC2630, the content-encryption key is concatenated with its length and padded to a multiple of 8, if required:
preparing
the content encryption key for the wrapping procedure.contentEncryptionKey
- the content encryption key for which to calculate the LCEKPAD valueprotected byte[] decomposeLCEKPAD(byte[] LCEKPAD) throws BadPaddingException
As last step of the RC2 Key UnWrap algorithm described in RFC2630, the
LCEKPAD (composed of cek-length, decrypted content-encryption key and optional
padding) has to be decomposed for getting the cek.
Since LCEKPAD also may be used by other key wrap algorithms
than RC2 (e.g. CAST-128 Key Wrap; RFC2984) this method may be used for
decomposing the LCEKPAD value when finishing
the unwrapping procedure.
LCEKPAD
- the LCEKPAD value (LENGTH || CEK || PAD)BadPaddingException
- if the PAD value of the LCEKPAD has a length
not shorter than 8public int engineGetOutputSize(int inLen)
update
or doFinal
operation including
any data currently being buffered.engineGetOutputSize
in class CipherSpi
inLen
- the number of bytes to processCipher.getOutputSize(int)
,
CipherSpi.engineGetOutputSize(int)
public int getModeBlockSize()
public int engineGetBlockSize()
engineGetBlockSize
in class CipherSpi
Cipher.getBlockSize()
,
CipherSpi.engineGetBlockSize()
protected int engineGetKeySize(Key key) throws InvalidKeyException
CipherSpi
engineGetKeySize
in class CipherSpi
|
This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note). | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |