|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--javax.crypto.CipherSpi | +--iaik.pkcs.pkcs1.RSACipher
This class implements the RSA algorithm through the Cipher interface.
An application can use this class to encrypt or decrypt data with RSA public and private keys.
The RSA (Rivest Shamir Adleman) algorithm is one of the most famous public-key
algortihms used for data encryption or digital signing based on modulo
multiplications. For data encryption, messages are encrypted using the public
key (modulus n
, public exponent e
) of some entity.
Since only this entity holds the corresponding private key (private exponent d),
nobody else would be able to decrypt the encrypted message. The public key
(n,e)
is derived by first chosing two random large primes,
p
and q
, from which the modulus is calculated by doing
n=pq
.
The public exponent e
must be chosen to be relatively prime to
(p-1)(q-1)
. The corresponding private exponent d
yields from the prediction that ed
has to be congruent to
1 mod(p-1)(q-1)
. Encrypting some message m
(of size less than n
) is done by the continued modulo multiplication
c =me(mod n)
, decrypting uses the formula
m =cd(mod n)
. (see "Applied Cryptography", Bruce Schneier,
ISBN 0-471-59756-2).
This class follows the methods described in PKCS#1 (Version 2.1) for
RSA en/decrypting some data, and supports both PKCS#1v1.2 encryption schemes,
RSAES-OAEP and RSAES-PKCS1-v1_5. PKCS#1v1.5 en/decryption also may be
used for PKCS#1v1.5 based signature calculation/verification.
but also supports the OEAP encryption scheme of PKCS#1 (Version 2.1).
The encryption process encrypts a given octet string to an encrypted octet
string using two integer values as parameters, denoting the modulus (n) and the
exponent (c), which either will represent the public exponent (e) or the private
exponent (d), depending on whether to perform a public-key or a private-key
operation. The decryption process decrypts a given encrypted octet string to
an octet string, again using two integer values as parameters, denoting the modulus
(n) and the exponent (c), which either will represent the public exponent (e) or the
private exponent (d), depending on whether to perform a public-key or a private-key
operation. Both encryption and decryption process first convert the given
octet-string data input to an integer, which is transformed back to give the octet
string output after doing the RSA computation. Before (respectively after) doing
initial octet-string-to-integer (respectively final integer-to-octet-string)
conversation, padding (unpadding) may be performed according to PKCS#1.
To en/decrypt data without any padding (encryption block formatting) an application may call
Cipher.getInstance("RSA/ECB/NoPadding");or
Cipher.getInstance("RSA/NONE/NoPadding");However, this is not recommended. Rather PKCS#1 (v1.5 or OAEP) padding should be used. The default padding scheme is PKCS#1v1.5. It may be explictly requested by by specifying "PKCS1Padding" when instantiating a RSA Cipher object, or by omitting mode and padding name from the transformation string:
Cipher.getInstance("RSA/ECB/PKCS1Padding");or
Cipher.getInstance("RSA/NONE/PKCS1Padding");is equivalent to:
Cipher.getInstance("RSA");
The padding block type will automatically be selected as 2 for public key encryption/
private key decryption and 1 for private key encryption/ public key decryption.
You can also explicitly specify the desiged block type using
Cipher.getInstance("RSA/n/PKCS1Padding")
where n is the padding type
(0, 1, or 2).
Code example:
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, RSAPrivateKey); // auto selects block type 1or
rsa.init(Cipher.ENCRYPT_MODE, RSAPublicKey); // auto selects block type 2 crypted = rsa.doFinal(data);
If you want to use OAEP es encryption scheme you have to specify "OAEP" as padding scheme when instantiating the cipher object:
Cipher rsa = Cipher.getInstance("RSA/ECB/OAEP");OAEP may be
parametrized
by hash function, mask generation function, and PSourceAlgorithm,
(see PKCS#1v2.1:
RSASES-OAEP-params :: = SEQUENCE { hashAlgorithm [0] HashAlgorithm DEFAULT sha1, maskGenerationAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty, } HashAlgorithm ::= AlgorithmIdentifer { {OAEP-PSSDigestAlgorithms} } MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} } PSourceAlgorithm ::= AlgorithmIdentifier { {PKCS1PSourceAlgorithms} }By default SHA-1 is used as hash function, MGF1 (with SHA-1 as hash function parameter) is used as mask generation algorithm, and id-pSpecified is used as PSourceAlgorithm (with an empty OCTET STRING as parameter). However, an application explicitly may supply parameters (as
RSAOaepParameterSpec
) when initializing a RSA Cipher object, e.g.:
// hash, mgf and pSource algorithm ids AlgorithmID hashID = (AlgorithmID)AlgorithmID.md5.clone(); AlgorithmID mgfID = (AlgorithmID)AlgorithmID.mgf1.clone(); mgfID.setParameter(hashID.toASN1Object()); AlgorithmID pSourceID = (AlgorithmID)AlgorithmID.pSpecified.clone(); byte[] label = ...; pSourceID.setParameter(new OCTET_STRING(label)); // hash and mgf engines MessageDigest hashEngine = hashID.getMessageDigestInstance(); MaskGenerationAlgorithm mgfEngine = mgfID.getMaskGenerationAlgorithmInstance(); MGF1ParameterSpec mgf1ParamSpec = new MGF1ParameterSpec(hashID); mgf1ParamSpec.setHashEngine(hashEngine); mgfEngine.setParameters(mgf1ParamSpec); // create the RSAOaepParameterSpec RSAOaepParameterSpec oaepParamSpec = new RSAOaepParameterSpec(hashID, mgfID, pSourceID); // set engines oaepParamSpec.setHashEngine(hashEngine); oaepParamSpec.setMGFEngine(mgfEngine); // create an init a RSA Cipher object: Cipher rsa = Cipher.getInstance("RSA/ECB/OAEP"); PublicKey publicKey = ...; rsa.init(Cipher.ENCRYPT_MODE, publicKey, oaepParamSpec); // encrypt some data byte[] data = ...; byte[] encrypted = rsa.doFinal(data);Please note that the Java Cryptography Extensions (JCE), only may allow to set the PSourceAlgorithm as
parameter
. All other parameters are specified by the padding name of the transformation
string when instantiating a RSA Cipher engine, e.g.:
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); RSAOaepPSourceParameterSpec paramSpec = new RSAOaepPSourceParameterSpec((AlgorithmID)AlgorithmID.pSpecified.clone()); byte[] label = ...; paramSpec.setLabel(label); rsa.init(Cipher.ENCRYPT_MODE, publicKey, paramSpec); byte[] encrypted = rsa.doFinal(data);An OAEP padding scheme that implements the, for instance, "OAEPWithSHA1AndMGF1Padding" (in general: OAEPWith<digest>And<mgf>Padding) has to use SHA-1 as hash- and MGF1 as mask generation algorithm. The IAIK provider supports OAEP padding for all implemented hash algorithms and the
MGF1
mask generation function.
This class uses blinding for private key operations per default.
This is especially useful for protocol implementations like SSL/TLS.
The performance decrease is below 10 percent in most cases if blinding is
used, but it can grow up to double processing time if the public exponent
of a key is randomly chosen and not a special value like 2^16 + 1.
In practice almost any public key has such a special exponent that
increases the performance.
An application can use the methods
isUseBlinding()
and setUseBlinding()
to determine
if blinding is used and to switch blinding on or off for this instance.
The methods isUseBlindingDefault()
and
setUseBlindingDefault()
determine and set the default.
Attention! Blinding can only be used if the public exponent is available.
This is the case if a CRT private
RSAPrivateCrtKey
key is used. If an
application uses an non-CRT private key and blinding is enabled, the
private key operation is processed without blinding.
Cipher
,
CipherSpi
,
RSAPrivateKey
,
RSAPublicKey
,
MaskGenerationAlgorithm
,
MGF1
,
MGF1ParameterSpec
,
MGF1Parameters
,
RSAOaepParameterSpec
,
RSAOaepPSourceParameterSpec
,
RSAOaepParameters
Field Summary | |
protected RSAPrivateKey |
privKey
The private key; used for private key de/encryption (PKCS#1v1.5), or private key decryption (OAEP). |
protected RSAPublicKey |
pubKey
The public key; used for public key en/decryption (PKCS#1v1.5), or public key encryption (OAEP). |
Constructor Summary | |
RSACipher()
Default Constructor for the RSA cipher. |
Method Summary | |
protected byte[] |
engineDoFinal(byte[] in,
int inOff,
int inLen)
En/decrypts the given data. |
protected int |
engineDoFinal(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
En/decrypts the given data. |
protected int |
engineGetBlockSize()
This method return 0, because this is not a block cipher. |
protected byte[] |
engineGetIV()
This method return null , because this cipher does not use
an IV. |
protected int |
engineGetKeySize(Key key)
Returns the size of the given RSA key. |
protected int |
engineGetOutputSize(int inputLen)
Returns 0 . |
protected AlgorithmParameters |
engineGetParameters()
Returns the algorithm parameters, if OAEP padding is used. |
protected void |
engineInit(int opmode,
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
Initializes this RSA cipher with given key and algorithm parameters. |
protected void |
engineInit(int opmode,
Key key,
AlgorithmParameters params,
SecureRandom random)
Initializes this RSA cipher with the given key. |
protected void |
engineInit(int opmode,
Key key,
SecureRandom random)
Initializes this RSA cipher with the given key. |
protected void |
engineSetMode(String mode)
Sets the tranformation mode. |
protected void |
engineSetPadding(String padding)
Sets the padding scheme of this cipher, which only can be "PKCS1Padding", "NoPadding", "PKCS1PaddingSSL2", or "OAEP", or OAEPWith<digest>And<mgf>Padding (e.g. |
protected Key |
engineUnwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm,
int wrappedKeyType)
Unwraps (RSA decrypts) the given wrapped key. |
protected byte[] |
engineUpdate(byte[] in,
int inOff,
int inLen)
This method is not implemented and only throws a RuntimeException. |
protected int |
engineUpdate(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
This method is not implemented and only throws a RuntimeException. |
protected byte[] |
engineWrap(Key key)
Wraps (RSA encrypts) the given key. |
protected SecureRandom |
getSecureRandom()
Gets the SecureRandom used by this Signature engine. |
boolean |
isUseBlinding()
Check if blinding is switched on. |
static boolean |
isUseBlindingDefault()
Check if blinding is switched on per default. |
protected byte[] |
rawCrypt(byte[] message)
RSA encrypts or decrypts the given message. |
BigInteger |
rawPrivateRSA(BigInteger message,
RSAPrivateKey privateKey,
Random random)
Process a raw RSA operation; i.e. a modulo exponentiation. |
BigInteger |
rawPublicRSA(BigInteger message,
RSAPublicKey publicKey)
Process a raw RSA operation; i.e. a simple modulo exponentiation. |
protected void |
setSecureRandom(SecureRandom random)
Sets the SecureRandom to be used by this Signature engine. |
boolean |
setUseBlinding(boolean useBlinding)
Switch blinding on or off. |
static boolean |
setUseBlindingDefault(boolean useBlindingDefault)
Switch blinding on or off by default. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected RSAPrivateKey privKey
protected RSAPublicKey pubKey
Constructor Detail |
public RSACipher()
This constructor only internally is used for initializing a RSA Cipher.
Applications should not call this constructor to get a RSA Cipher;
they should call one of the Cipher.getInstance
factory methods instead.
Cipher.getInstance(java.lang.String)
Method Detail |
public static boolean isUseBlindingDefault()
true
.true
, if blinding is used by default.setUseBlindingDefault(boolean)
,
rawPrivateRSA(java.math.BigInteger, java.security.interfaces.RSAPrivateKey, java.util.Random)
,
setUseBlinding(boolean)
,
isUseBlinding()
public static boolean setUseBlindingDefault(boolean useBlindingDefault)
useBlinding
- true
to switch on blinding per default,
false
to switch it off.isUseBlindingDefault()
,
rawPrivateRSA(java.math.BigInteger, java.security.interfaces.RSAPrivateKey, java.util.Random)
,
setUseBlinding(boolean)
,
isUseBlinding()
public boolean isUseBlinding()
true
.true
, if blinding is used.setUseBlinding(boolean)
,
rawPrivateRSA(java.math.BigInteger, java.security.interfaces.RSAPrivateKey, java.util.Random)
,
setUseBlindingDefault(boolean)
,
isUseBlindingDefault()
public boolean setUseBlinding(boolean useBlinding)
useBlinding
- true
to switch on blinding,
false
to switch it off.isUseBlinding()
,
rawPrivateRSA(java.math.BigInteger, java.security.interfaces.RSAPrivateKey, java.util.Random)
,
setUseBlindingDefault(boolean)
,
isUseBlindingDefault()
public BigInteger rawPrivateRSA(BigInteger message, RSAPrivateKey privateKey, Random random)
privateKey
argument is a CRT key which contains the public
exponent, this method performs blinding to counter timing attacks.
This is especially useful for protocol implementations like SSL/TLS.
If the blinding argument is provided (i.e. it is not null
),
this random object is used to generate the blinding factor. If it is
null
, the current default random
(@see iaik.security.random.SecRandom) will be used.message
- The message to be decryped.privateKey
- The private key providing the key parameters. This must
be a CRT key which provides the public exponent to
support blinding.random
- The random object to be used for generating the blinding
factor. If null
, the current default random
is used.isUseBlinding()
,
setUseBlinding(boolean)
,
SecRandom.getDefault()
public BigInteger rawPublicRSA(BigInteger message, RSAPublicKey publicKey)
message
- The message to encrypt.publicKey
- The public key providing the public exponent and modulus.protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException
Before a cipher object is ready for data processing, it has to be initialized
according to the desired cryptographic operation, which is specified by the
opmode
parameter (either ENCRYPT_MODE or DECRYPT_MODE, or WRAP_MODE
or UNWRAP_MODE).
The key either will be a RSAPrivateKey or a RSAPublicKey, depending on the specific cryptographic operation to be performed. Please note that for RSA ciphers that use OAEP padding a private key only is allowed for decryption and a public key only is allowed for encryption since OAEP does not support signature creation/verification.
Applications shall use the corresponding init
method of
javax.crypto.Cipher
for provider independently initializing a RSA cipher.
engineInit
in class CipherSpi
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE or Cipher.WRAP_MODE or Cipher.UNWRAP_MODEkey
- an instance of a RSA PublicKey or RSA PrivateKeyrandom
- source of randomnessInvalidKeyException
- if the key is invalid (not a valid RSA key), or
if PKCS1Padding is used and the key is not appropriate for the block type, or
if OAEP padding is used and private key is tried to be used for an encryption operation
or a public key is tried to be for a decryption operationprotected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException, InvalidKeyException
Before a cipher object is ready for data processing, it has to be initialized
according to the desired cryptographic operation, which is specified by the
opmode
parameter (either ENCRYPT_MODE or DECRYPT_MODE, or WRAP_MODE
or UNWRAP_MODE).
The key either will be a RSAPrivateKey or a RSAPublicKey, depending on the specific cryptographic operation to be performed. Please note that for RSA ciphers that use OAEP padding a private key only is allowed for decryption and a public key only is allowed for encryption since OAEP does not support signature creation/verification.
Parameters (RSAOaepParameterSpec
or
RSAOaepPSourceParameterSpec
are only allowed for OAEP padding.
Applications shall use the corresponding init
method of
javax.crypto.Cipher
for provider independently initializing
a RSA cipher.
engineInit
in class CipherSpi
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE or Cipher.WRAP_MODE or Cipher.UNWRAP_MODEkey
- an instance of a RSA PublicKey or RSA PrivateKeyparams
- algorithm parameters that may be used for OAEP paddingrandom
- source of randomnessInvalidAlgorithmParameterException
- if OAEP padding is not used or the parameters
are invalid (not a instance of RSAOaepParameterSpec
or RSAOaepPSourceParameterSpec
InvalidKeyException
- if the key is invalid (not a valid RSA key), or
if PKCS1Padding is used and the key is not appropriate for the block type, or
if OAEP padding is used and private key is tried to be used for an encryption operation
or a public key is tried to be for a decryption operationprotected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidAlgorithmParameterException, InvalidKeyException
Before a cipher object is ready for data processing, it has to be initialized
according to the desired cryptographic operation, which is specified by the
opmode
parameter (either ENCRYPT_MODE or DECRYPT_MODE, or WRAP_MODE
or UNWRAP_MODE).
The key either will be a RSAPrivateKey or a RSAPublicKey, depending on the specific cryptographic operation to be performed. Please note that for RSA ciphers that use OAEP padding a private key only is allowed for decryption and a public key only is allowed for encryption since OAEP does not support signature creation/verification.
Parameters are only allowed for OAEP padding.
Applications shall use the corresponding init
method of
javax.crypto.Cipher
for provider independently initializing
a RSA cipher.
engineInit
in class CipherSpi
opmode
- Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE or Cipher.WRAP_MODE or Cipher.UNWRAP_MODEkey
- an instance of a RSA PublicKey or RSA PrivateKeyparams
- algorithm parameters that may be used for OAEP paddingrandom
- source of randomnessInvalidAlgorithmParameterException
- if OAEP padding is not used or the parameters
are invalid (not usable for OAEP padding)InvalidKeyException
- if the key is invalid (not a valid RSA key), or
if PKCS1Padding is used and the key is not appropriate for the block type, or
if OAEP padding is used and private key is tried to be used for an encryption operation
or a public key is tried to be for a decryption operationprotected AlgorithmParameters engineGetParameters()
engineGetParameters
in class CipherSpi
null
otherwiseprotected void engineSetPadding(String padding) throws NoSuchPaddingException
engineSetPadding
in class CipherSpi
padding
- the padding scheme for this RSA cipherNoSuchPaddingException
- if the requested padding algorithm is not supported, or
cannot be supported (because, for instance, required
parameters are not available)protected void engineSetMode(String mode)
For PKCS#1v1.5 padding this might be "ECB" (automatic block type selection)
or the padding block type ("0" or "1" for a private key operation, and "2" for a
public key operation.
For OAEP only the transformation mode is ignored (only "ECB" may be valid)
engineSetMode
in class CipherSpi
the
- transformation mode ("ECB" or PKCS#1v1.5 block type ("0","1" or "2")protected byte[] engineUpdate(byte[] in, int inOff, int inLen)
engineUpdate
in class CipherSpi
RuntimeException
- This Method is not supported.protected int engineUpdate(byte[] in, int inOff, int inLen, byte[] out, int outOff)
engineUpdate
in class CipherSpi
RuntimeException
- This Method is not supported.protected byte[] rawCrypt(byte[] message)
message
- the message to en/decryptprotected int engineGetOutputSize(int inputLen)
0
.engineGetOutputSize
in class CipherSpi
protected byte[] engineGetIV()
null
, because this cipher does not use
an IV.engineGetIV
in class CipherSpi
null
.protected int engineGetBlockSize()
engineGetBlockSize
in class CipherSpi
protected int engineDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws ShortBufferException, BadPaddingException
Applications shall use the corresponding doFinal
method of
javax.crypto.Cipher
for provider
independent doing the data en/decryption.
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted. 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 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 writtenShortBufferException
- if the given output buffer is too small for holding the resultBadPaddingException
- if a padding problem occursCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
protected byte[] engineDoFinal(byte[] in, int inOff, int inLen) throws BadPaddingException
Applications shall use the corresponding doFinal
method of
javax.crypto.Cipher
for provider independently
doing the data en/decryption.
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted. The result is returned as an output byte array.
engineDoFinal
in class 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 processedBadPaddingException
- if a padding problem occursCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
protected int engineGetKeySize(Key key) throws InvalidKeyException
engineGetKeySize
in class CipherSpi
key
- the key for which the size should be calculatedInvalidKeyException
- if the given key is not a RSA keyprotected byte[] engineWrap(Key key) throws InvalidKeyException
engineWrap
in class CipherSpi
key
- the key to be wrappedInvalidKeyException
- if the key to be wrapped cannot be encoded or
an problem occurs during wrapping the keyprotected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException
engineUnwrap
in class CipherSpi
wrappedKey
- the wrapped key to be unwrappedwrappedKeyAlgorithm
- the algorithm name of the wrapped keywrappedKeyType
- (SECRET_KEY, PRIVATE_KEY, or PUBLIC_KEY)InvalidKeyException
- if a problem occurs when unwrapping the wrapped keyNoSuchAlgorithmException
- if no KeyFactory for the requested wrappedKeyAlgorithm
is availableprotected void setSecureRandom(SecureRandom random)
random
- the SecureRandom to be used by this signature engineprotected SecureRandom getSecureRandom()
SecRandom
|
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 |