iaik.cms
Class IaikProvider

java.lang.Object
  extended by iaik.cms.SecurityProvider
      extended by iaik.cms.IaikProvider
Direct Known Subclasses:
IaikCCProvider, IaikEccProvider

public class IaikProvider
extends SecurityProvider

This class implements a CMS SecurityProvider for the IAIK-JCE cryptographic provider "IAIK".

See Also:
SecurityProvider

Field Summary
static java.lang.String ALG_SIGNATURE_RAWRSA
          Constant string RawRSA.
static java.lang.String ALG_SIGNATURE_RAWRSASSA_PKCS1_V15
          Constant string RawRSASSA-PKCS1-v1_5.
 
Fields inherited from class iaik.cms.SecurityProvider
ALG_CIPHER_RSA, ALG_CIPHER_RSA_DECRYPT, ALG_CIPHER_RSA_ENCRYPT, ALG_CIPHER_RSA_SIGN, ALG_CIPHER_RSA_VERIFY, ALG_DIGEST_MD5, ALG_DIGEST_SHA, ALG_HMAC_MD5, ALG_HMAC_SHA, ALG_KEYEX_DH, ALG_KEYEX_ESDH, ALG_KEYEX_SSDH, ALG_SIGNATURE_RAWDSA, ALG_SIGNATURE_RAWECDSA, ALG_SIGNATURE_RAWECDSA_PLAIN, ALG_SIGNATURE_RAWRSAPSS, ALG_SIGNATURE_SHADSA, CIPHER_DECRYPT, CIPHER_ENCRYPT, CIPHER_NONE, CIPHER_UNWRAP, CIPHER_WRAP, COMPRESS, DECOMPRESS, IMPLEMENTATION_NAME_DSA, IMPLEMENTATION_NAME_ECDSA, IMPLEMENTATION_NAME_ECDSA_PLAIN, IMPLEMENTATION_NAME_PBKDF2, IMPLEMENTATION_NAME_PWRI_KEK, IMPLEMENTATION_NAME_RSA, IMPLEMENTATION_NAME_RSA_OAEP, IMPLEMENTATION_NAME_RSA_PSS, providerName_, random_, SIGNATURE_NONE, SIGNATURE_SIGN, SIGNATURE_VERIFY
 
Constructor Summary
IaikProvider()
          Default Constructor.
 
Method Summary
 byte[] calculateSignatureFromHash(AlgorithmID signatureAlgorithm, AlgorithmID digestAlgorithm, java.security.PrivateKey privateKey, byte[] digest)
          Calculates the signature value for a CMS SignerInfo over the given digest value with the given algorithm using the supplied private key.
 byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm, AlgorithmID digestAlgorithm, java.security.PrivateKey privateKey, byte[] signedAttributes)
          Calculates the signature value for a CMS SignerInfo over the given signed attributes with the given algorithm using the supplied private key.
 void checkDomainParameters(java.security.PrivateKey myKey, java.security.PublicKey otherKey)
          Checks if the given private and public key agreement keys have the same domain parameters.
 javax.crypto.SecretKey createSharedKeyEncryptionKey(AlgorithmID keyAgreeAlg, java.security.PrivateKey myKey, java.security.PublicKey otherKey, AlgorithmID kea, int kekLength, byte[] ukm, java.lang.String kekName)
          Create a shared secret key encryption key for the given key agree algorithm.
 javax.crypto.SecretKey decryptKey(byte[] encryptedKey, AlgorithmID kea, java.security.PrivateKey recipientKey, java.lang.String cekAlgorithmName)
          Decrypts the given encrypted content encryption key for a KeyTransRecipientInfo.
 java.security.Key deriveKey(char[] password, AlgorithmID keyDerivationAlg, java.security.spec.AlgorithmParameterSpec paramSpec)
          Uses the requested key derivation function to create a secret key from the supplied password.
 javax.crypto.SecretKey generateKey(AlgorithmID algorithm, int keyLength)
          Generates a SecretKey for the requested algorithm.
 java.security.KeyPair generateKeyAgreementKeyPair(AlgorithmID keyAgreeAlgorithm, java.security.PublicKey otherKey)
          Generates a key pair with same domain parameters as the given public key for the given key agreement method.
 java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(AlgorithmID algID)
          Gets algorithm parameter specification from the given AlgorithmID.
 ASN1Object getASN1OriginatorPublicKey(java.security.PublicKey originatorPublicKey)
          Gets an ASN.1 representation of the provided originator public key.
 java.security.Key getPBEKey(char[] password, AlgorithmID pbeAlg)
          Creates secret key from the supplied password using the specified PBE algorithm.
 java.security.SecureRandom getSecureRandom()
          Returns an instance of the default SecureRandom class set in iaik.security.random.SecRandom.
 java.security.spec.AlgorithmParameterSpec setIv(java.security.AlgorithmParameters params, byte[] iv)
          Creates an AlgorithmParameterSpec containing any parameters from the given AlgorithmParameters object and the given iv.
static void turnOffIAIKProviderVersionCheck()
          If the IAIK crypto provider is used but its version is not appropriate for this version of IAIK-CMS, an warning message is printed to System.out to use a more recent version of IAIK-JCE.
 javax.crypto.SecretKey unwrapKey(byte[] wrappedCek, AlgorithmID kea, java.security.Key kek, java.security.AlgorithmParameters params, java.lang.String cekAlgName)
          Unwraps the given wrapped (encrypted) secret content encryption key for a KEKRecipientInfo or KeyAgreeRecipientInfo.
 boolean verifySignatureFromHash(AlgorithmID signatureAlgorithm, AlgorithmID digestAlgorithm, java.security.PublicKey publicKey, byte[] digest, byte[] signatureValue)
          Verifies the signature value of a CMS SignerInfo object with the given algorithm using the supplied public key.
 boolean verifySignatureFromSignedAttributes(AlgorithmID signatureAlgorithm, AlgorithmID digestAlgorithm, java.security.PublicKey publicKey, byte[] signedAttributes, byte[] signatureValue)
          Verifies the signature value of a CMS SignerInfo calculated over the given signed attributes with the given algorithm using the supplied public key.
 byte[] wrapKey(javax.crypto.SecretKey cek, AlgorithmID kea, java.security.Key kek, java.security.AlgorithmParameters params)
          Wraps the given secret content encryption key for a KEKRecipientInfo or KeyAgreeRecipientInfo, or PasswordRecipientInfo.
 
Methods inherited from class iaik.cms.SecurityProvider
calculateMac, calculateSharedSecret, compress, convertCipherMode, decryptKey, encryptKey, generateKey, getAlgorithmParameters, getAlgorithmParameters, getAlgorithmParameters, getAuthCipherEngine, getAuthCipherEngine, getByteArrayAuthCipherEngine, getByteArrayAuthCipherEngine, getByteArrayCipherEngine, getByteArrayCipherEngine, getCipher, getCipher, getCipher, getCipher, getHash, getInputStreamAuthCipherEngine, getInputStreamAuthCipherEngine, getInputStreamCipherEngine, getInputStreamCipherEngine, getInputStreamCompressEngine, getInputStreamHashEngine, getInputStreamMacEngine, getKeyAgreement, getKeyFactory, getKeyGenerator, getKeyGenerator, getKeyLength, getKeyLength, getKeyLength, getKeyPairGenerator, getMac, getMac, getMessageDigest, getMessageDigest, getMicAlgs, getOriginatorPublicKey, getOutputStreamCompressEngine, getOutputStreamHashEngine, getOutputStreamMacEngine, getProviderName, getSecretKeyFactory, getSecurityProvider, getSignature, getSignature, getSignature, getSignature, getSignatureParameters, setSecureRandom, setSecurityProvider, setSignatureParameters
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ALG_SIGNATURE_RAWRSA

public static final java.lang.String ALG_SIGNATURE_RAWRSA
Constant string RawRSA. Used by this provider with getSignature().

See Also:
Constant Field Values

ALG_SIGNATURE_RAWRSASSA_PKCS1_V15

public static final java.lang.String ALG_SIGNATURE_RAWRSASSA_PKCS1_V15
Constant string RawRSASSA-PKCS1-v1_5. Used by this provider with getSignature().

See Also:
Constant Field Values
Constructor Detail

IaikProvider

public IaikProvider()
Default Constructor. Tries to add the provider IAIK.

Method Detail

calculateSignatureFromSignedAttributes

public byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm,
                                                     AlgorithmID digestAlgorithm,
                                                     java.security.PrivateKey privateKey,
                                                     byte[] signedAttributes)
                                              throws java.security.NoSuchAlgorithmException,
                                                     java.security.InvalidKeyException,
                                                     java.security.SignatureException
Calculates the signature value for a CMS SignerInfo over the given signed attributes with the given algorithm using the supplied private key.

Each SignerInfo included in a CMS SignedData object may calculate the signature value differently depending on the presence of signed attributes:

This method is called by class SignerInfo for calculating the signature when signed attributes are present.

When writing your own SecurityProvider and overriding this method, be aware that only the -- yet NOT hashed -- DER encoding of the signed attributes is supplied to this method. For that reason this method can be overriden for use with smartcards requiring to do the digest calculation theirselves: ensure that your SignerInfo contains signed attributes and override this method in a way to pass the given DER encoding of the signed attributes to your smartcard for doing the signature (and digest) calculation.

Since this method requires to calculate the digest value over the DER encoded signed attributes as part of the signature calculation, it uses a ordinary JCA Signature engine.

Overrides:
calculateSignatureFromSignedAttributes in class SecurityProvider
Parameters:
signatureAlgorithm - signatureAlgorithm the signature algorithm to be used, e.g. rsaEncryption, DSA
digestAlgorithm - the digest algorithm to be used for hash computation (e.g. SHA-1,..., SHA-512); may be necessary for some signature schemes (e.g. to be included as a DigestInfo in a PKCS#1 RSA signature)
privateKey - the private key of the signer (i.e. the one supplied when creating a SignerInfo object; may be some kind of "dummy" key when used for smartcards
signedAttributes - the DER encoding of the signed attributes over which the signature shall be calculated
Returns:
the signature value calculated from the given DER encoded signed attributes
Throws:
java.security.NoSuchAlgorithmException - if no Signature engine is available for the requested algorithm
java.security.InvalidKeyException - if the key is not valid
if - signature calculation fails
java.security.SignatureException

calculateSignatureFromHash

public byte[] calculateSignatureFromHash(AlgorithmID signatureAlgorithm,
                                         AlgorithmID digestAlgorithm,
                                         java.security.PrivateKey privateKey,
                                         byte[] digest)
                                  throws java.security.NoSuchAlgorithmException,
                                         java.security.InvalidKeyException,
                                         java.security.SignatureException
Calculates the signature value for a CMS SignerInfo over the given digest value with the given algorithm using the supplied private key.

Each SignerInfo included in a CMS SignedData object may calculate the signature value differently depending on the presence of signed attributes:

This method is called by class SignerInfo for calculating the signature when no signed attributes are present. Since the data to be signed may be of arbitrary size this method expects the already hashed data to only calculate the signature value on it (for instance, by doing the digest encrypting when using RSA for signing).

For that reason, when writing your own SecurityProvider and overriding this method, you will need some kind of RAW signature (respectively digest encryption) mechanism only expecting the already hashed data (e.g. a "RawDSA" signature engine when using DSA repectively a Cipher engine when using RSA).

If you want to override this method for use with smartcards, please be sure that your smartcard is able to do the signature (respectively digest encryption) operation only. However, if your smartcard requires to supply the whole data for doing the hash calcualtion itself, you may ensure that your SignerInfo contains signed attributes and override method calculateSignatureFromSignedAttributes for calculating the signature over the DER encoding of the signed attributes (thereby doing the hash computation, too).

Overrides:
calculateSignatureFromHash in class SecurityProvider
Parameters:
signatureAlgorithm - signatureAlgorithm the signature algorithm to be used, e.g. rsaEncryption, DSA
digestAlgorithm - the digest algorithm used for hash computation (e.g. SHA-1, ..., SHA-512); may be necessary for some signature schemes (e.g. to be included as a DigestInfo in a PKCS#1 RSA signature)
privateKey - the private key of the signer (i.e. the one supplied when creating a SignerInfo object; may be some kind of "dummy" key when used for smartcards
digest - the digest value over which the signature shall be calculated
Returns:
the signature value calculated from the given digest value
Throws:
java.security.NoSuchAlgorithmException - if any of the required algorithms is not supported
java.security.InvalidKeyException - if the key is not valid
java.security.SignatureException - if signature verification fails because of some crypto related error

verifySignatureFromSignedAttributes

public boolean verifySignatureFromSignedAttributes(AlgorithmID signatureAlgorithm,
                                                   AlgorithmID digestAlgorithm,
                                                   java.security.PublicKey publicKey,
                                                   byte[] signedAttributes,
                                                   byte[] signatureValue)
                                            throws java.security.NoSuchAlgorithmException,
                                                   java.security.InvalidKeyException,
                                                   java.security.SignatureException
Verifies the signature value of a CMS SignerInfo calculated over the given signed attributes with the given algorithm using the supplied public key.

Each SignerInfo included in a CMS SignedData object may calculate the signature value differently depending on the presence of signed attributes:

This method is called by class SignerInfo for verifying the signature when no signed attributes are present.

When writing your own SecurityProvider and overriding this method, be aware that only the -- yet NOT hashed -- DER encoding of the signed attributes is supplied to this method. Although generally for public key operations smartcards may not be used, this method can be overriden for use with smartcards requiring to do the digest calculation theirselves: ensure that your SignerInfo contains signed attributes and override this method in a way to pass the given DER encoding of the signed attributes to your smartcard for doing the signature verification (including any digest calculation required).

Since this method requires to calculate the digest value over the DER encoded signed attributes as part of the signature verification, it uses a oridinary JCA Signature engine.

Overrides:
verifySignatureFromSignedAttributes in class SecurityProvider
Parameters:
signatureAlgorithm - signatureAlgorithm the signature algorithm to be used, e.g. rsaEncryption, DSA
digestAlgorithm - the digest algorithm to be used for hash computation (e.g. SHA-1, ..., SHA-512);
publicKey - the public key of the signer
signedAttributes - the DER encoding of the signed attributes over which the signature has been calculated
signatureValue - the signatureValue the signature value to be verified
Returns:
true if the signature is ok, false if not
Throws:
java.security.NoSuchAlgorithmException - if any of the required algorithms is not supported
java.security.InvalidKeyException - if the key is not valid
java.security.SignatureException - if signature verification fails because of some computation error

verifySignatureFromHash

public boolean verifySignatureFromHash(AlgorithmID signatureAlgorithm,
                                       AlgorithmID digestAlgorithm,
                                       java.security.PublicKey publicKey,
                                       byte[] digest,
                                       byte[] signatureValue)
                                throws java.security.NoSuchAlgorithmException,
                                       java.security.InvalidKeyException,
                                       java.security.SignatureException
Verifies the signature value of a CMS SignerInfo object with the given algorithm using the supplied public key.

Each SignerInfo included in a CMS SignedData object may calculate the signature value differently depending on the presence of signed attributes:

This method is called by class SignerInfo for verifying the signature when no signed attributes are present. Since the data to be verified may be of arbitrary size this method expects the already hashed data to only be verified against the signature value.

For that reason, when writing your own SecurityProvider and overriding this method, you will need some kind of RAW signature (respectively "encrypted digest decryption") mechanism only expecting the already hashed data (e.g. a "RawDSA" signature engine when using DSA or "RawRSA" signature engine when using RSA).

Although generally for public key operations smartcards may not be used, when overriding this method for use with smartcards, please be sure that your smartcard is able to do the signature verification operation only. However, if your smartcard requires to supply the whole data for doing the hash calcualtion itself, you may ensure that your SignerInfo contains signed attributes and override method verifySignatureFromSignedAttributes for verifying the signature calculated from the DER encoding of the signed attributes (thereby doing the hash computation, too).

Overrides:
verifySignatureFromHash in class SecurityProvider
Parameters:
signatureAlgorithm - signatureAlgorithm the signature algorithm to be used for verification, e.g. rsaEncryption, DSA
digestAlgorithm - the digest algorithm that has been used for hash computation (e.g. SHA-1, ..., SHA-512); may be necessary for some signature schemes (e.g. to be check against a DigestInfo in a PKCS#1 RSA signature)
publicKey - the public key of the signer
digest - the digest value to be verified
Returns:
true if the signature is ok, false if not
Throws:
java.security.NoSuchAlgorithmException - if any of the required algorithms is not supported
java.security.InvalidKeyException - if the key is not valid
java.security.SignatureException - if signature verification fails because of some crypto related or parsing error

decryptKey

public javax.crypto.SecretKey decryptKey(byte[] encryptedKey,
                                         AlgorithmID kea,
                                         java.security.PrivateKey recipientKey,
                                         java.lang.String cekAlgorithmName)
                                  throws java.security.NoSuchAlgorithmException,
                                         java.security.InvalidKeyException,
                                         javax.crypto.NoSuchPaddingException,
                                         javax.crypto.BadPaddingException
Decrypts the given encrypted content encryption key for a KeyTransRecipientInfo.

CMS EnvelopedData uses the KeyTransRecipientInfo type for encrypting the secret content encryption key with the public key of the recipient. Currently in general RSA PKCS#1v1.5 is used for key transport. If rsaEncryption is requested as key encryption algorithm this method uses a RSA Cipher ("RSA/ECB/PKCS1Padding/Encrypt") for decrypting the encrypted content encryption key with the supplied private key of the recipient. If another algorithm than RSA is requested, this method throws a NoSuchAlgorithmException. An application wishing to support another algorithm may override this method.

Overrides:
decryptKey in class SecurityProvider
Parameters:
encryptedKey - the encrypted content encryption key to be decrypted
kea - the key encryption alglorithm to be used, e.g. rsaEncryption
recipientKey - the private key of the recipient to be used for decrypting the encrypted content encryption key
cekAlgorithmName - the name of the content encryption key (e.g. "DES") to be set for the SecretKey object created by this method
Returns:
the decrypted content encryption key
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.InvalidKeyException - if the decryption key is not valid
javax.crypto.NoSuchPaddingException - if the required padding scheme is not supported
javax.crypto.BadPaddingException - if an padding error occurs

createSharedKeyEncryptionKey

public javax.crypto.SecretKey createSharedKeyEncryptionKey(AlgorithmID keyAgreeAlg,
                                                           java.security.PrivateKey myKey,
                                                           java.security.PublicKey otherKey,
                                                           AlgorithmID kea,
                                                           int kekLength,
                                                           byte[] ukm,
                                                           java.lang.String kekName)
                                                    throws java.security.NoSuchAlgorithmException,
                                                           java.security.InvalidKeyException,
                                                           java.security.InvalidAlgorithmParameterException
Create a shared secret key encryption key for the given key agree algorithm.

Creating a shared key encryption key is required when a key agreement algorithm is used as key management protocol for the recipient of an EnvelopedData or AuthenticatedData object. The shared key encryption key will be used by an KeyAgreeRecipientInfo to encrypt the secret content encryption key or Mac key.

This method only works for Ephemeral and Static Static Difiie Hellman (ESDH, SSDH).

Overrides:
createSharedKeyEncryptionKey in class SecurityProvider
Parameters:
keyAgreeAlg - the key agreement algorithm
myKey - the private key agreement key of the one party
otherKey - the public key agreement key of the other party
kea - the key ancryption algorithm (may be required for kek generation)
kekLength - the length of the shared key encryption key to be generated
ukm - any user keying material that may be required for kek generation
kekName - the name of the key encryption algorithm
Returns:
the shared key encryption key generated
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.InvalidKeyException - if there is a key related problem
java.security.InvalidAlgorithmParameterException - if the parameters are invalid

checkDomainParameters

public void checkDomainParameters(java.security.PrivateKey myKey,
                                  java.security.PublicKey otherKey)
                           throws java.security.InvalidParameterException
Checks if the given private and public key agreement keys have the same domain parameters.

If the supplied keys are ESDH keys the parameters are checked. Otherwiese super.checkDomainParameters is called.

Overrides:
checkDomainParameters in class SecurityProvider
Parameters:
myKey - the private key of the first party
otherKey - the public key of the other party
Throws:
InvalidParameterEyception - if the domain parameters do not match
java.security.InvalidParameterException

generateKeyAgreementKeyPair

public java.security.KeyPair generateKeyAgreementKeyPair(AlgorithmID keyAgreeAlgorithm,
                                                         java.security.PublicKey otherKey)
                                                  throws java.security.NoSuchAlgorithmException,
                                                         java.security.InvalidKeyException,
                                                         java.security.InvalidAlgorithmParameterException
Generates a key pair with same domain parameters as the given public key for the given key agreement method.

This method is called by the library for creating the originator key pair if the OriginatorPublicKey alternative is used for representing the public key of the originator within a KeyAgreeRecipientInfo. The public key supplied to this method is the one of the recipient and the key pair returned by this method must have domain parameters matching to those of the given recipient public key. Note that ephemeral static Diffie Hellmean (ESDH) is the default key agreement method used by the CMS types EnvelopedData and AuthenticatedData. According RFC 5652 the OriginatorPublicKey has to be used for representing the public key of the originator if ESDH is used as key agreement algorithm.

Overrides:
generateKeyAgreementKeyPair in class SecurityProvider
Parameters:
keyAgreeAlgorithm - the key agreement algorithm to be used
otherKey - the public key of the other party
Returns:
the originator key pair with domain parameters matching to those of the supplied key of the other party
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.InvalidKeyException - if the key is not appropriate for the key agreement algorithm
java.security.InvalidAlgorithmParameterException - if the parameters are invalid

getASN1OriginatorPublicKey

public ASN1Object getASN1OriginatorPublicKey(java.security.PublicKey originatorPublicKey)
                                      throws CMSException
Gets an ASN.1 representation of the provided originator public key.

For some key agree algorithms CMS may require a special key encoding for the KeyAgreeRecipientInfo OriginatorPublicKey choice. According to RFC 3370 (Cryptographic Message Syntax Algorithms), ESDH public keys have to be encoded with absent parameters in their AlgorithmID field when encoded as originator public keys:

 The originatorKey algorithm field MUST contain the dh-public-number
 object identifier with absent parameters.  The originatorKey
 publicKey field MUST contain the sender's ephemeral public key.
 
If the supplied key is an ESDH key this method returns an ASN.1 representation with absent parameters. Otherwise it simply calls super.getASN1OriginatorPublicKey.

Overrides:
getASN1OriginatorPublicKey in class SecurityProvider
Parameters:
originatorPublicKey - the originator public key from which to get an ASN.1 representation
Returns:
the ASN.1 representation of the originator public key
Throws:
CMSException - if the key cannot be ASN.1 represented

getAlgorithmParameterSpec

public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(AlgorithmID algID)
                                                                    throws java.security.spec.InvalidParameterSpecException
Gets algorithm parameter specification from the given AlgorithmID.

The IaikProvider uses this method to get paramaters from an RSA-PSS signature algorithm id. If PSS parameters are included, they are returned as iaik.pkcs.pkcs1.RSAPssParameterSpec object; otherwise (for any other algorithm) this method returns null.

Overrides:
getAlgorithmParameterSpec in class SecurityProvider
Parameters:
algID - the AlgorithmID from which to get the parameter specification
Returns:
a RSAPssParameterSpec object, if the supplied AlgorithmID specifies the RSA-PSS signature algorithm (with included parameters); null for any other algorithm
Throws:
java.security.InvalidParameterException - if an error occurs when trying to fetch the algorithm parameter specification
java.security.spec.InvalidParameterSpecException

getPBEKey

public java.security.Key getPBEKey(char[] password,
                                   AlgorithmID pbeAlg)
                            throws java.security.NoSuchAlgorithmException,
                                   java.security.spec.InvalidKeySpecException
Creates secret key from the supplied password using the specified PBE algorithm. If a PKCS#5 PBE algorithm is used, a PBEKey is created, otherwise (for PKCS#12 PBE algorithms) a PBEKeyBMP. (pbeWithMD5AndDES_CBC (PKCS#5) needs a PBEKey and all the pbe ciphers defined in PKCS#12 need a PBEKeyBMP).

Overrides:
getPBEKey in class SecurityProvider
Parameters:
password - the password for creating the secret key
pbeAlg - the PBE algorithm to be used
Returns:
the secret key as instance of PBEKey or PBEKeyBMP
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.spec.InvalidKeySpecException - if the key cannot be created from the password specification

deriveKey

public java.security.Key deriveKey(char[] password,
                                   AlgorithmID keyDerivationAlg,
                                   java.security.spec.AlgorithmParameterSpec paramSpec)
                            throws java.security.NoSuchAlgorithmException,
                                   java.security.InvalidAlgorithmParameterException
Uses the requested key derivation function to create a secret key from the supplied password. This method only is implemented for the PKCS#5 key derivation function PBKDF2. For any other key derivation algorithm the deriveKey method of the super SecurityProvider class is called. If PBKDF2 is used, the parameters may be suppled as IAIK-JCE iaik.security.spec.PBEKeyAndParameterSpec (password, salt, iteration count, derived key length) or as javax.crypto.spec.PBEParameterSpec (salt, iteration count). If the parameters are given as PBEKeyAndParameterSpec the application has take care to ensure that the passwords supplied by the password parameter and in the PBEKeyAndParameterSpec parameter are identical (i.e. this method does not look if they are the same). If no parameters are supplied they maybe parsed from the key derivation algorithm id.

Overrides:
deriveKey in class SecurityProvider
Parameters:
password - the password for creating the secret key
keyDerivationAlg - the key derivation function to be used
paramSpec - any required algorithm parameters; may be null if no parameters are required or the parameters are supplied via the AlgorithmID; may also contain the password in which case the password parameter maybe null;
Returns:
the secret key
Throws:
java.security.NoSuchAlgorithmException - if the requested key derivation function is not available
java.security.InvalidAlgorithmParameterException - if the parameters are invalid or cannot be parsed from the algorithmID

wrapKey

public byte[] wrapKey(javax.crypto.SecretKey cek,
                      AlgorithmID kea,
                      java.security.Key kek,
                      java.security.AlgorithmParameters params)
               throws java.security.NoSuchAlgorithmException,
                      java.security.InvalidKeyException,
                      java.security.InvalidAlgorithmParameterException,
                      javax.crypto.IllegalBlockSizeException,
                      javax.crypto.BadPaddingException
Wraps the given secret content encryption key for a KEKRecipientInfo or KeyAgreeRecipientInfo, or PasswordRecipientInfo.

This method only is implemented for wrapping a content encryption key with the PWRI-KEK ("1.2.840.113549.1.9.16.3.9") algorithm presented in RFC 3211 (Password-based Encryption for CMS), section 2.3.1:

 The key wrap algorithm is performed in two phases, a first phase which
 formats the CEK into a form suitable for encryption by the KEK, and a
 second phase which wraps the formatted CEK using the KEK.

 Key formatting: Create a formatted CEK block consisting of the
 following:

  1. A one-byte count of the number of bytes in the CEK.

  2. A check value containing the bitwise complement of the first
     three bytes of the CEK.

  3. The CEK.

  4. Enough random padding data to make the CEK data block a
     multiple of the KEK block length and at least two KEK cipher
     blocks long (the fact that 32 bits of count+check value are
     used means that even with a 40-bit CEK, the resulting data size
     will always be at least two (64-bit) cipher blocks long).  The
     padding data does not have to be cryptographically strong,
     although unpredictability helps.  Note that PKCS #5 padding is
     not used, since the length of the data is already known.

 The formatted CEK block then looks as follows:

  CEK byte count || check value || CEK || padding (if required)

 Key wrapping:

  1. Encrypt the padded key using the KEK.
  2. Without resetting the IV (that is, using the last ciphertext
     block as the IV), encrypt the encrypted padded key a second
     time.

 The resulting double-encrypted data is the EncryptedKey.
 
For any other key encryption algorithm (kea) method wrapKey of super class SecurityProvider is called.

For PWRI-KEK this method expects that the kea algorithm ID contains the kek encryption algorithm (and any associated parameters) to be used. Any parameters supplied by params are ignored. The supplied kek key encryption key already has to be the one derived from a password (if PBE is used).

Since PWRI-KEK requires the usage of initialization vectors it only may work properly with kek ciphers and modes using theiselves an iv (e.g. TripleDES in CBC mode.

Overrides:
wrapKey in class SecurityProvider
Parameters:
cek - the secret content encryption key to be wrapped (encrypted)
kea - the key wrap (encryption) alglorithm to be used, PWRI-KEK
kek - the key encryption key to be used for encrypting the content encryption key
params - any algorithm parameters required for initializing the key encryption cipher; ignored for PWRI-KEK
Returns:
the wrapped (encrypted) content encryption key as byte array
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.InvalidKeyException - if the key encryption key is not valid
java.security.InvalidAlgorithmParameterException - if the parameters cannot be parsed from the kea algorithm id or are not valid
javax.crypto.IllegalBlockSizeException - if the cipherblock size is not correct
javax.crypto.BadPaddingException - if an padding error occurs

unwrapKey

public javax.crypto.SecretKey unwrapKey(byte[] wrappedCek,
                                        AlgorithmID kea,
                                        java.security.Key kek,
                                        java.security.AlgorithmParameters params,
                                        java.lang.String cekAlgName)
                                 throws java.security.NoSuchAlgorithmException,
                                        java.security.InvalidKeyException,
                                        java.security.InvalidAlgorithmParameterException
Unwraps the given wrapped (encrypted) secret content encryption key for a KEKRecipientInfo or KeyAgreeRecipientInfo.

This method only is implemented for unwrapping an encrypted content encryption key with the PWRI-KEK ("1.2.840.113549.1.9.16.3.9") algorithm presented in RFC 3211 (Password-based Encryption for CMS), section 2.3.2:

 2.3.2 Key Unwrap
 
 Key unwrapping:
 
    1. Using the n-1'th ciphertext block as the IV, decrypt the n'th
       ciphertext block.
 
    2. Using the decrypted n'th ciphertext block as the IV, decrypt
       the 1st ... n-1'th ciphertext blocks.  This strips the outer
       layer of encryption.
 
    3. Decrypt the inner layer of encryption using the KEK.
 
 Key format verification:
 
   1a. If the CEK byte count is less than the minimum allowed key
       size (usually 5 bytes for 40-bit keys) or greater than the
       wrapped CEK length or not valid for the CEK algorithm (eg not
       16 or 24 bytes for triple DES), the KEK was invalid.
 
   1b. If the bitwise complement of the key check value doesn't match
       the first three bytes of the key, the KEK was invalid.
 
For any other key encryption algorithm (kea) method unwrapKey of super class SecurityProvider is called.

For PWRI-KEK this method expects that the kea algorithm ID contains the kek encryption algorithm (and any associated parameters) to be used. Any parameters supplied by params are ignored. The supplied kek key encryption key already has to be the one derived from a password (if PBE is used).

Since PWRI-KEK requires the usage of initialization vectors it only may work properly with kek ciphers and modes using theirselves an iv (e.g. TripleDES in CBC mode). For that reason it is not possible to implement PWRI-KEK in really algorithm independet manner. For instance, the RC2 algorithm not only uses an iv, but also a second parameter from which the effective key length is calculated. So a RC2 cipher in CBC mode has to be initialized with iv and the effective key length parameters. As seen from above, the PWRI-KEK algorithm initializes decryption algorithm three times, but only the last (innermost) decryption phase uses the iv included in the kek algorithm id. For RC2 this means that the RC2 Cipher engine has to be initialized three times with same effective key length (derived from the kek AlgorithmID parameters) but different iv (only the last got from the AlgorithmID parameters). For that reason this method gets the algorithm parameters from the kek AlgorithmID and then calls method setIv to convert the (RC2) AlgorithmParameters into a (RC2) AlgorithmParameterSpec object containing the requested iv:

 ...
 AlgorithmParameters kekParams = kekEncrAlgID.getAlgorithmParameters();
 byte[] iv = ...;
 AlgorithmParameterSpec kekParamSpec = setIv(kekParams, iv)
 
For algorithms that only use an iv as parameter, method setIv simply returns an IvParameterSpec object with the given iv.

Also unwrap step 1a from the key format verification cannot be implemented in algorithm independet manner:

   1a. If the CEK byte count is less than the minimum allowed key
       size (usually 5 bytes for 40-bit keys) or greater than the
       wrapped CEK length or not valid for the CEK algorithm (eg not
       16 or 24 bytes for triple DES), the KEK was invalid.
 
Ckecking if the CEK byte count is greater than the wrapped CEK is quite easy, however looking if the CEK byte count is less than the minimum allowed key size or not valid for the CEK algorithm requires information of the kek algorithm itself. However, a violatoin of any of these two requirements will be detected later when attemping to use the unwrapped CEK with the cooresponding Cipher engine. Thus checking this could be omitted here.

Overrides:
unwrapKey in class SecurityProvider
Parameters:
wrappedCek - the wrapped secret content encryption key to be unwrapped (decrypted)
kea - the key (un)wrap (en/decryption) alglorithm to be used, PWRI-KEK
kek - the key encryption key to be used for decrypting the encrypted content encryption key
params - any algorithm parameters required for initializing the cipher; ignored for PWRI-KEK
cekAlgName - the name of the content encryption cipher (required by the unwrap method of a JCE cipher engine)
Returns:
the unwrapped (decrypted) content encryption key
Throws:
java.security.NoSuchAlgorithmException - if the requested algorithm is not available
java.security.InvalidKeyException - if the key encryption key is not valid
java.security.InvalidAlgorithmParameterException - if the parameters cannot be parsed or are not valid

setIv

public java.security.spec.AlgorithmParameterSpec setIv(java.security.AlgorithmParameters params,
                                                       byte[] iv)
                                                throws java.security.spec.InvalidParameterSpecException
Creates an AlgorithmParameterSpec containing any parameters from the given AlgorithmParameters object and the given iv. This method is called by method unwrapKey for obtaining an algorithm dependent parameter specification containing the iv required by the PWRI-KEK unwrap algorithm as specified in RFC 3211 (Password-based Encryption for CMS), section 2.3.2:
 2.3.2 Key Unwrap
 
 Key unwrapping:
 
    1. Using the n-1'th ciphertext block as the IV, decrypt the n'th
       ciphertext block.
 
    2. Using the decrypted n'th ciphertext block as the IV, decrypt
       the 1st ... n-1'th ciphertext blocks.  This strips the outer
       layer of encryption.
 
    3. Decrypt the inner layer of encryption using the KEK.
 
 Key format verification:
 
   1a. If the CEK byte count is less than the minimum allowed key
       size (usually 5 bytes for 40-bit keys) or greater than the
       wrapped CEK length or not valid for the CEK algorithm (eg not
       16 or 24 bytes for triple DES), the KEK was invalid.
 
   1b. If the bitwise complement of the key check value doesn't match
       the first three bytes of the key, the KEK was invalid.
 

Since PWRI-KEK requires the usage of initialization vectors it only may work properly with kek ciphers and modes using theirselves an iv (e.g. TripleDES in CBC mode). For that reason it is not possible to implement PWRI-KEK in really algorithm independet manner. For instance, the RC2 algorithm not only uses an iv, but also a second parameter from which the effective key length is calculated. So a RC2 cipher in CBC mode has to be initialized with iv and the effective key length parameters. As seen from above, the PWRI-KEK algorithm initializes decryption algorithm three times, but only the last (innermost) decryption phase uses the iv included in the kek algorithm id. For RC2 this means that the RC2 Cipher engine has to be initialized three times with same effective key length (derived from the kek AlgorithmID parameters) but different iv (only the last got from the AlgorithmID parameters). For that reason this method is used to convert the (RC2) AlgorithmParameters got from the KEK algorithmID into a (RC2) AlgorithmParameterSpec object containing the requested iv:

 ...
 AlgorithmParameters kekParams = kekEncrAlgID.getAlgorithmParameters();
 byte[] iv = ...;
 AlgorithmParameterSpec kekParamSpec = setIv(kekParams, iv)
 
For algorithms that only use an iv as parameter,this method simply returns an IvParameterSpec object with the given iv.

Parameters:
params - the AlgorithmParameters (CAST128Parameters, RC2Parameters, RC5Parameters, IvParameters, etc., or null
iv - the iv to be set
Returns:
an AlgorithmParameterSpec object with the given iv and any other parameter values obtained from the supplied AlgorithmParameters (i.e. a CAST128ParameterSpec, RC2ParameterSpec, or RC5ParameterSpec object for CAST128, RC2, or RC5 parameters, or an IvParameterSpec object in any other case
Throws:
java.security.spec.InvalidParameterSpecException - if the parameter specification cannot be built

getSecureRandom

public java.security.SecureRandom getSecureRandom()
Returns an instance of the default SecureRandom class set in iaik.security.random.SecRandom. By default this method returns a new SecureRandom anytime when called. However, when a SecureRandom has been explicitly set by calling method setSecureRandom, this SecureRandom is returned.

Overrides:
getSecureRandom in class SecurityProvider
Returns:
the SecureRandom

generateKey

public javax.crypto.SecretKey generateKey(AlgorithmID algorithm,
                                          int keyLength)
                                   throws java.security.NoSuchAlgorithmException
Generates a SecretKey for the requested algorithm.

Overrides:
generateKey in class SecurityProvider
Parameters:
algorithm - the requested algorithm
keyLength - the length of the key to be generated, may be required for algorithms with variable key size
Returns:
the generated secret key
Throws:
NoSuchSuchAlgorithmException - if the key for the requested algorithm cannot be created
java.security.NoSuchAlgorithmException

turnOffIAIKProviderVersionCheck

public static void turnOffIAIKProviderVersionCheck()
If the IAIK crypto provider is used but its version is not appropriate for this version of IAIK-CMS, an warning message is printed to System.out to use a more recent version of IAIK-JCE. This warning message can be turned off when calling this method.


This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

IAIK-CMS 5.1, (c) 2002 IAIK, (c) 2003 - 2010 SIC