mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-18 23:05:03 -05:00
1510 lines
62 KiB
Java
1510 lines
62 KiB
Java
package javax.crypto;
|
|
|
|
import java.util.StringTokenizer;
|
|
import java.security.Key;
|
|
import java.security.Provider;
|
|
import java.security.SecureRandom;
|
|
import java.security.AlgorithmParameters;
|
|
import java.security.InvalidKeyException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.NoSuchProviderException;
|
|
import java.security.InvalidAlgorithmParameterException;
|
|
import java.security.cert.Certificate;
|
|
import java.security.spec.AlgorithmParameterSpec;
|
|
|
|
/**
|
|
* This class provides the functionality of a cryptographic cipher for
|
|
* encryption and decryption. It forms the core of the Java Cryptographic
|
|
* Extension (JCE) framework.
|
|
* <p>
|
|
* In order to create a Cipher object, the application calls the
|
|
* Cipher's <code>getInstance</code> method, and passes the name of the
|
|
* requested <i>transformation</i> to it. Optionally, the name of a provider
|
|
* may be specified.
|
|
* <p>
|
|
* A <i>transformation</i> is a string that describes the operation (or
|
|
* set of operations) to be performed on the given input, to produce some
|
|
* output. A transformation always includes the name of a cryptographic
|
|
* algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
|
|
* padding scheme.
|
|
*
|
|
* <p> A transformation is of the form:<p>
|
|
*
|
|
* <ul>
|
|
* <li>"<i>algorithm/mode/padding</i>" or
|
|
* <p>
|
|
* <li>"<i>algorithm</i>"
|
|
* </ul>
|
|
*
|
|
* <P> (in the latter case,
|
|
* provider-specific default values for the mode and padding scheme are used).
|
|
* For example, the following is a valid transformation:<p>
|
|
*
|
|
* <pre>
|
|
* Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
|
|
* </pre>
|
|
* <p>
|
|
* When requesting a block cipher in stream cipher mode (e.g.,
|
|
* <code>DES</code> in <code>CFB</code> or <code>OFB</code> mode), the user may
|
|
* optionally specify the number of bits to be
|
|
* processed at a time, by appending this number to the mode name as shown in
|
|
* the "<i>DES/CFB8/NoPadding</i>" and "<i>DES/OFB32/PKCS5Padding</i>"
|
|
* transformations. If no such number is specified, a provider-specific default
|
|
* is used. (For example, the "SunJCE" provider uses a default of 64 bits.)
|
|
*/
|
|
public class Cipher
|
|
{
|
|
static private final int UNINITIALIZED = 0;
|
|
|
|
static public final int ENCRYPT_MODE = 1;
|
|
static public final int DECRYPT_MODE = 2;
|
|
static public final int WRAP_MODE = 3;
|
|
static public final int UNWRAP_MODE = 4;
|
|
|
|
static public final int PUBLIC_KEY = 1;
|
|
static public final int PRIVATE_KEY = 2;
|
|
static public final int SECRET_KEY = 3;
|
|
|
|
private CipherSpi cipherSpi;
|
|
private Provider provider;
|
|
private String transformation;
|
|
|
|
private int mode = UNINITIALIZED;
|
|
|
|
/**
|
|
* Creates a Cipher object.
|
|
*
|
|
* @param cipherSpi the delegate
|
|
* @param provider the provider
|
|
* @param transformation the transformation
|
|
*/
|
|
protected Cipher(
|
|
CipherSpi cipherSpi,
|
|
Provider provider,
|
|
String transformation)
|
|
{
|
|
this.cipherSpi = cipherSpi;
|
|
this.provider = provider;
|
|
this.transformation = transformation;
|
|
}
|
|
|
|
/**
|
|
* Generates a <code>Cipher</code> object that implements the specified
|
|
* transformation.
|
|
* <p>
|
|
* If the default provider package supplies an implementation of the
|
|
* requested transformation, an instance of <code>Cipher</code> containing
|
|
* that implementation is returned.
|
|
* If the transformation is not available in the default provider package,
|
|
* other provider packages are searched.
|
|
*
|
|
* @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>.
|
|
* See Appendix A in the Java Cryptography Extension API Specification & Reference
|
|
* for information about standard transformation names.
|
|
*
|
|
* @return a cipher that implements the requested transformation
|
|
* @exception NoSuchAlgorithmException if the specified transformation is not available in the default
|
|
* provider package or any of the other provider packages that were searched.
|
|
* @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme that is
|
|
* not available.
|
|
*/
|
|
public static final Cipher getInstance(
|
|
String transformation)
|
|
throws NoSuchAlgorithmException, NoSuchPaddingException
|
|
{
|
|
try
|
|
{
|
|
JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, (String) null);
|
|
|
|
if (imp != null)
|
|
{
|
|
return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation);
|
|
}
|
|
|
|
//
|
|
// try the long way
|
|
//
|
|
StringTokenizer tok = new StringTokenizer(transformation, "/");
|
|
String algorithm = tok.nextToken();
|
|
|
|
imp = JCEUtil.getImplementation("Cipher", algorithm, (String) null);
|
|
|
|
if (imp == null)
|
|
{
|
|
throw new NoSuchAlgorithmException(transformation + " not found");
|
|
}
|
|
|
|
CipherSpi cipherSpi = (CipherSpi)imp.getEngine();
|
|
|
|
//
|
|
// make sure we don't get fooled by a "//" in the string
|
|
//
|
|
if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2))
|
|
{
|
|
cipherSpi.engineSetMode(tok.nextToken());
|
|
}
|
|
|
|
if (tok.hasMoreTokens())
|
|
{
|
|
cipherSpi.engineSetPadding(tok.nextToken());
|
|
}
|
|
|
|
return new Cipher(cipherSpi, imp.getProvider(), transformation);
|
|
}
|
|
catch (NoSuchProviderException e)
|
|
{
|
|
throw new NoSuchAlgorithmException(transformation + " not found");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a <code>Cipher</code> object that implements the specified
|
|
* transformation, as supplied by the specified provider.
|
|
*
|
|
* @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>.
|
|
* See Appendix A in the Java Cryptography Extension API Specification & Reference
|
|
* for information about standard transformation names.
|
|
*
|
|
* @param provider the provider
|
|
* @return a cipher that implements the requested transformation
|
|
* @exception NoSuchAlgorithmException if no transformation was specified, or if the specified
|
|
* transformation is not available from the specified provider.
|
|
* @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme
|
|
* that is not available.
|
|
*/
|
|
public static final Cipher getInstance(
|
|
String transformation,
|
|
Provider provider)
|
|
throws NoSuchAlgorithmException, NoSuchPaddingException
|
|
{
|
|
if (transformation == null)
|
|
{
|
|
throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()");
|
|
}
|
|
|
|
JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider);
|
|
|
|
if (imp != null)
|
|
{
|
|
return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation);
|
|
}
|
|
|
|
//
|
|
// try the long way
|
|
//
|
|
StringTokenizer tok = new StringTokenizer(transformation, "/");
|
|
String algorithm = tok.nextToken();
|
|
|
|
imp = JCEUtil.getImplementation("Cipher", algorithm, provider);
|
|
|
|
if (imp == null)
|
|
{
|
|
throw new NoSuchAlgorithmException(transformation + " not found");
|
|
}
|
|
|
|
CipherSpi cipherSpi = (CipherSpi)imp.getEngine();
|
|
|
|
//
|
|
// make sure we don't get fooled by a "//" in the string
|
|
//
|
|
if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2))
|
|
{
|
|
cipherSpi.engineSetMode(tok.nextToken());
|
|
}
|
|
|
|
if (tok.hasMoreTokens())
|
|
{
|
|
cipherSpi.engineSetPadding(tok.nextToken());
|
|
}
|
|
|
|
return new Cipher(cipherSpi, imp.getProvider(), transformation);
|
|
}
|
|
|
|
/**
|
|
* Creates a <code>Cipher</code> object that implements the specified
|
|
* transformation, as supplied by the specified provider.
|
|
*
|
|
* @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>.
|
|
* See Appendix A in the Java Cryptography Extension API Specification & Reference
|
|
* for information about standard transformation names.
|
|
*
|
|
* @param provider the name of the provider
|
|
* @return a cipher that implements the requested transformation
|
|
* @exception NoSuchAlgorithmException if no transformation was specified, or if the specified
|
|
* transformation is not available from the specified provider.
|
|
* @exception NoSuchProviderException if the specified provider has not been configured.
|
|
* @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme
|
|
* that is not available.
|
|
*/
|
|
public static final Cipher getInstance(
|
|
String transformation,
|
|
String provider)
|
|
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException
|
|
{
|
|
if (transformation == null)
|
|
{
|
|
throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()");
|
|
}
|
|
|
|
JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider);
|
|
|
|
if (imp != null)
|
|
{
|
|
return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation);
|
|
}
|
|
|
|
//
|
|
// try the long way
|
|
//
|
|
StringTokenizer tok = new StringTokenizer(transformation, "/");
|
|
String algorithm = tok.nextToken();
|
|
|
|
imp = JCEUtil.getImplementation("Cipher", algorithm, provider);
|
|
|
|
if (imp == null)
|
|
{
|
|
throw new NoSuchAlgorithmException(transformation + " not found");
|
|
}
|
|
|
|
CipherSpi cipherSpi = (CipherSpi)imp.getEngine();
|
|
|
|
//
|
|
// make sure we don't get fooled by a "//" in the string
|
|
//
|
|
if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2))
|
|
{
|
|
cipherSpi.engineSetMode(tok.nextToken());
|
|
}
|
|
|
|
if (tok.hasMoreTokens())
|
|
{
|
|
cipherSpi.engineSetPadding(tok.nextToken());
|
|
}
|
|
|
|
return new Cipher(cipherSpi, imp.getProvider(), transformation);
|
|
}
|
|
|
|
/**
|
|
* Returns the provider of this <code>Cipher</code> object.
|
|
*
|
|
* @return the provider of this <code>Cipher</code> object
|
|
*/
|
|
public final Provider getProvider()
|
|
{
|
|
return provider;
|
|
}
|
|
|
|
/**
|
|
* Returns the algorithm name of this <code>Cipher</code> object.
|
|
* <p>
|
|
* This is the same name that was specified in one of the
|
|
* <code>getInstance</code> calls that created this <code>Cipher</code>
|
|
* object..
|
|
*
|
|
* @return the algorithm name of this <code>Cipher</code> object.
|
|
*/
|
|
public final String getAlgorithm()
|
|
{
|
|
return transformation;
|
|
}
|
|
|
|
/**
|
|
* Returns the block size (in bytes).
|
|
*
|
|
* @return the block size (in bytes), or 0 if the underlying algorithm is not a block cipher
|
|
*/
|
|
public final int getBlockSize()
|
|
{
|
|
return cipherSpi.engineGetBlockSize();
|
|
}
|
|
|
|
/**
|
|
* Returns the length in bytes that an output buffer would need to be in
|
|
* order to hold the result of the next <code>update</code> or
|
|
* <code>doFinal</code> operation, given the input length <code>inputLen</code> (in bytes).
|
|
* <p>
|
|
* This call takes into account any unprocessed (buffered) data from a
|
|
* previous <code>update</code> call, and padding.
|
|
* <p>
|
|
* The actual output length of the next <code>update</code> or
|
|
* <code>doFinal</code> call may be smaller than the length returned by
|
|
* this method.
|
|
*
|
|
* @param inputLen the input length (in bytes)
|
|
* @return the required output buffer size (in bytes)
|
|
* @exception java.lang.IllegalStateException if this cipher is in a wrong state (e.g., has not
|
|
* yet been initialized)
|
|
*/
|
|
public final int getOutputSize(
|
|
int inputLen)
|
|
throws IllegalStateException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
return cipherSpi.engineGetOutputSize(inputLen);
|
|
}
|
|
|
|
/**
|
|
* Returns the initialization vector (IV) in a new buffer.
|
|
* <p>
|
|
* This is useful in the case where a random IV was created,
|
|
* or in the context of password-based encryption or decryption, where the IV
|
|
* is derived from a user-supplied password.
|
|
*
|
|
* @return the initialization vector in a new buffer, or null if the
|
|
* underlying algorithm does not use an IV, or if the IV has not yet been set.
|
|
*/
|
|
public final byte[] getIV()
|
|
{
|
|
return cipherSpi.engineGetIV();
|
|
}
|
|
|
|
/**
|
|
* Returns the parameters used with this cipher.
|
|
* <p>
|
|
* The returned parameters may be the same that were used to initialize
|
|
* this cipher, or may contain a combination of default and random
|
|
* parameter values used by the underlying cipher implementation if this
|
|
* cipher requires algorithm parameters but was not initialized with any.
|
|
*
|
|
* @return the parameters used with this cipher, or null if this cipher
|
|
* does not use any parameters.
|
|
*/
|
|
public final AlgorithmParameters getParameters()
|
|
{
|
|
return cipherSpi.engineGetParameters();
|
|
}
|
|
|
|
/**
|
|
* Returns the exemption mechanism object used with this cipher.
|
|
*
|
|
* @return the exemption mechanism object used with this cipher, or
|
|
* null if this cipher does not use any exemption mechanism.
|
|
*/
|
|
public final ExemptionMechanism getExemptionMechanism()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters that cannot be
|
|
* derived from the given <code>key</code>, the underlying cipher
|
|
* implementation is supposed to generate the required parameters itself
|
|
* (using provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidKeyException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them using the <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html">
|
|
* <code>SecureRandom</code></a> implementation of the highest-priority
|
|
* installed provider as the source of randomness.
|
|
* (If none of the installed providers supply an implementation of
|
|
* SecureRandom, a system-provided source of randomness will be used.)
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the following:
|
|
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
|
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
|
* @param key the key
|
|
* @exception InvalidKeyException if the given key is inappropriate for
|
|
* initializing this cipher, or if this cipher is being initialized for
|
|
* decryption and requires algorithm parameters that cannot be
|
|
* determined from the given key, or if the given key has a keysize that
|
|
* exceeds the maximum allowable keysize (as determined from the
|
|
* configured jurisdiction policy files). Note: Jurisdiction files are ignored
|
|
* in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key)
|
|
throws InvalidKeyException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, new SecureRandom());
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key and a source of randomness.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters that cannot be
|
|
* derived from the given <code>key</code>, the underlying cipher
|
|
* implementation is supposed to generate the required parameters itself
|
|
* (using provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidKeyException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#engineGetParameters()">engineGetParameters</a> or
|
|
* <a href = "#engineGetIV()">engineGetIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them from <code>random</code>.
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
|
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
|
* @param key the encryption key
|
|
* @param random the source of randomness
|
|
* @exception InvalidKeyException if the given key is inappropriate for
|
|
* initializing this cipher, or if this cipher is being initialized for
|
|
* decryption and requires algorithm parameters that cannot be
|
|
* determined from the given key, or if the given key has a keysize that
|
|
* exceeds the maximum allowable keysize (as determined from the
|
|
* configured jurisdiction policy files). Note: Jurisdiction files are ignored
|
|
* in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key,
|
|
SecureRandom random)
|
|
throws InvalidKeyException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, random);
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key and a set of algorithm parameters.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters and
|
|
* <code>params</code> is null, the underlying cipher implementation is
|
|
* supposed to generate the required parameters itself (using
|
|
* provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidAlgorithmParameterException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them using the
|
|
* <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html">
|
|
* <code>SecureRandom</code></a> implementation of the highest-priority
|
|
* installed provider as the source of randomness.
|
|
* (If none of the installed providers supply an implementation of
|
|
* SecureRandom, a system-provided source of randomness will be used.)
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
|
|
* or <code>UNWRAP_MODE</code>)
|
|
* @param key the encryption key
|
|
* @param params the algorithm parameters
|
|
* @exception InvalidKeyException if the given key is inappropriate for initializing this
|
|
* cipher, or its keysize exceeds the maximum allowable keysize (as determined from the
|
|
* configured jurisdiction policy files).
|
|
* @exception InvalidAlgorithmParameterException if the given algorithm parameters are
|
|
* inappropriate for this cipher, or this cipher is being initialized for decryption and
|
|
* requires algorithm parameters and <code>params</code> is null, or the given algorithm
|
|
* parameters imply a cryptographic strength that would exceed the legal limits (as determined
|
|
* from the configured jurisdiction policy files). Note: Jurisdiction files are ignored
|
|
* in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key,
|
|
AlgorithmParameterSpec params)
|
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, params, new SecureRandom());
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key, a set of algorithm
|
|
* parameters, and a source of randomness.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters and
|
|
* <code>params</code> is null, the underlying cipher implementation is
|
|
* supposed to generate the required parameters itself (using
|
|
* provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidAlgorithmParameterException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them from <code>random</code>.
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
|
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
|
* @param key the encryption key
|
|
* @param params the algorithm parameters
|
|
* @param random the source of randomness
|
|
* @exception InvalidKeyException if the given key is inappropriate for
|
|
* initializing this cipher, or its keysize exceeds the maximum allowable
|
|
* keysize (as determined from the configured jurisdiction policy files).
|
|
* @exception InvalidAlgorithmParameterException if the given algorithm
|
|
* parameters are inappropriate for this cipher,
|
|
* or this cipher is being initialized for decryption and requires
|
|
* algorithm parameters and <code>params</code> is null, or the given
|
|
* algorithm parameters imply a cryptographic strength that would exceed
|
|
* the legal limits (as determined from the configured jurisdiction
|
|
* policy files).
|
|
* Note: Jurisdiction files are ignored in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key,
|
|
AlgorithmParameterSpec params,
|
|
SecureRandom random)
|
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, params, random);
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key and a set of algorithm
|
|
* parameters.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters and
|
|
* <code>params</code> is null, the underlying cipher implementation is
|
|
* supposed to generate the required parameters itself (using
|
|
* provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidAlgorithmParameterException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them using the
|
|
* <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html">
|
|
* <code>SecureRandom</code></a> implementation of the highest-priority
|
|
* installed provider as the source of randomness.
|
|
* (If none of the installed providers supply an implementation of
|
|
* SecureRandom, a system-provided source of randomness will be used.)
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
|
|
* or <code>UNWRAP_MODE</code>)
|
|
* @param key the encryption key
|
|
* @param params the algorithm parameters
|
|
* @exception InvalidKeyException if the given key is inappropriate for
|
|
* initializing this cipher, or its keysize exceeds the maximum allowable
|
|
* keysize (as determined from the configured jurisdiction policy files).
|
|
* @exception InvalidAlgorithmParameterException if the given algorithm
|
|
* parameters are inappropriate for this cipher,
|
|
* or this cipher is being initialized for decryption and requires
|
|
* algorithm parameters and <code>params</code> is null, or the given
|
|
* algorithm parameters imply a cryptographic strength that would exceed
|
|
* the legal limits (as determined from the configured jurisdiction
|
|
* policy files).
|
|
* Note: Jurisdiction files are ignored in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key,
|
|
AlgorithmParameters params)
|
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, params, new SecureRandom());
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with a key, a set of algorithm
|
|
* parameters, and a source of randomness.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters and
|
|
* <code>params</code> is null, the underlying cipher implementation is
|
|
* supposed to generate the required parameters itself (using
|
|
* provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidAlgorithmParameterException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them from <code>random</code>.
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
|
|
* or <code>UNWRAP_MODE</code>)
|
|
* @param key the encryption key
|
|
* @param params the algorithm parameters
|
|
* @param random the source of randomness
|
|
* @exception InvalidKeyException if the given key is inappropriate for
|
|
* initializing this cipher, or its keysize exceeds the maximum allowable
|
|
* keysize (as determined from the configured jurisdiction policy files).
|
|
* @exception InvalidAlgorithmParameterException if the given algorithm
|
|
* parameters are inappropriate for this cipher,
|
|
* or this cipher is being initialized for decryption and requires
|
|
* algorithm parameters and <code>params</code> is null, or the given
|
|
* algorithm parameters imply a cryptographic strength that would exceed
|
|
* the legal limits (as determined from the configured jurisdiction
|
|
* policy files).
|
|
* Note: Jurisdiction files are ignored in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Key key,
|
|
AlgorithmParameters params,
|
|
SecureRandom random)
|
|
throws InvalidKeyException, InvalidAlgorithmParameterException
|
|
{
|
|
cipherSpi.engineInit(opmode, key, params, random);
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with the public key from the given certificate.
|
|
* <p>
|
|
* The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping or key unwrapping, depending
|
|
* on the value of <code>opmode</code>.
|
|
* <p>
|
|
* If the certificate is of type X.509 and has a <i>key usage</i>
|
|
* extension field marked as critical, and the value of the <i>key usage</i>
|
|
* extension field implies that the public key in
|
|
* the certificate and its corresponding private key are not
|
|
* supposed to be used for the operation represented by the value
|
|
* of <code>opmode</code>,
|
|
* an <code>InvalidKeyException</code>
|
|
* is thrown.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters that cannot be
|
|
* derived from the public key in the given certificate, the underlying
|
|
* cipher
|
|
* implementation is supposed to generate the required parameters itself
|
|
* (using provider-specific default or ramdom values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an <code>
|
|
* InvalidKeyException</code> if it is being initialized for decryption or
|
|
* key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#getParameters()">getParameters</a> or
|
|
* <a href = "#getIV()">getIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them using the
|
|
* <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html">
|
|
* <code>SecureRandom</code></a>
|
|
* implementation of the highest-priority installed provider as the source of randomness.
|
|
* (If none of the installed providers supply an implementation of
|
|
* SecureRandom, a system-provided source of randomness will be used.)
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following:
|
|
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
|
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
|
* @param certificate the certificate
|
|
* @exception InvalidKeyException if the public key in the given
|
|
* certificate is inappropriate for initializing this cipher, or this
|
|
* cipher is being initialized for decryption or unwrapping keys and
|
|
* requires algorithm parameters that cannot be determined from the
|
|
* public key in the given certificate, or the keysize of the public key
|
|
* in the given certificate has a keysize that exceeds the maximum
|
|
* allowable keysize (as determined by the configured jurisdiction policy
|
|
* files).
|
|
* Note: Jurisdiction files are ignored in this implementation.
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Certificate certificate)
|
|
throws InvalidKeyException
|
|
{
|
|
cipherSpi.engineInit(opmode, certificate.getPublicKey(), new SecureRandom());
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Initializes this cipher with the public key from the given certificate
|
|
* and a source of randomness.
|
|
* <p>The cipher is initialized for one of the following four operations:
|
|
* encryption, decryption, key wrapping
|
|
* or key unwrapping, depending on
|
|
* the value of <code>opmode</code>.
|
|
* <p>
|
|
* If the certificate is of type X.509 and has a <i>key usage</i>
|
|
* extension field marked as critical, and the value of the <i>key usage</i>
|
|
* extension field implies that the public key in
|
|
* the certificate and its corresponding private key are not
|
|
* supposed to be used for the operation represented by the value of
|
|
* <code>opmode</code>,
|
|
* an <code>InvalidKeyException</code>
|
|
* is thrown.
|
|
* <p>
|
|
* If this cipher requires any algorithm parameters that cannot be
|
|
* derived from the public key in the given <code>certificate</code>,
|
|
* the underlying cipher
|
|
* implementation is supposed to generate the required parameters itself
|
|
* (using provider-specific default or random values) if it is being
|
|
* initialized for encryption or key wrapping, and raise an
|
|
* <code>InvalidKeyException</code> if it is being
|
|
* initialized for decryption or key unwrapping.
|
|
* The generated parameters can be retrieved using
|
|
* <a href = "#engineGetParameters()">engineGetParameters</a> or
|
|
* <a href = "#engineGetIV()">engineGetIV</a> (if the parameter is an IV).
|
|
* <p>
|
|
* If this cipher (including its underlying feedback or padding scheme)
|
|
* requires any random bytes (e.g., for parameter generation), it will get
|
|
* them from <code>random</code>.
|
|
* <p>
|
|
* Note that when a Cipher object is initialized, it loses all
|
|
* previously-acquired state. In other words, initializing a Cipher is
|
|
* equivalent to creating a new instance of that Cipher and initializing
|
|
* it.
|
|
*
|
|
* @param opmode the operation mode of this cipher (this is one of the
|
|
* following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
|
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
|
* @param certificate the certificate
|
|
* @param random the source of randomness
|
|
* @exception InvalidKeyException if the public key in the given
|
|
* certificate is inappropriate for initializing this cipher, or this
|
|
* cipher is being initialized for decryption or unwrapping keys and
|
|
* requires algorithm parameters that cannot be determined from the
|
|
* public key in the given certificate, or the keysize of the public key
|
|
* in the given certificate has a keysize that exceeds the maximum
|
|
* allowable keysize (as determined by the configured jurisdiction policy
|
|
* files).
|
|
*/
|
|
public final void init(
|
|
int opmode,
|
|
Certificate certificate,
|
|
SecureRandom random)
|
|
throws InvalidKeyException
|
|
{
|
|
cipherSpi.engineInit(opmode, certificate.getPublicKey(), random);
|
|
mode = opmode;
|
|
}
|
|
|
|
/**
|
|
* Continues a multiple-part encryption or decryption operation
|
|
* (depending on how this cipher was initialized), processing another data
|
|
* part.
|
|
* <p>
|
|
* The bytes in the <code>input</code> buffer are processed, and the
|
|
* result is stored in a new buffer.
|
|
* <p>
|
|
* If <code>input</code> has a length of zero, this method returns
|
|
* <code>null</code>.
|
|
*
|
|
* @param input the input buffer
|
|
* @return the new buffer with the result, or null if the underlying
|
|
* cipher is a block cipher and the input data is too short to result in a
|
|
* new block.
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
*/
|
|
public final byte[] update(
|
|
byte[] input)
|
|
throws IllegalStateException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input buffer");
|
|
}
|
|
|
|
if (input.length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return cipherSpi.engineUpdate(input, 0, input.length);
|
|
}
|
|
|
|
/**
|
|
* Continues a multiple-part encryption or decryption operation
|
|
* (depending on how this cipher was initialized), processing another data
|
|
* part.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, are processed,
|
|
* and the result is stored in a new buffer.
|
|
* <p>
|
|
* If <code>inputLen</code> is zero, this method returns
|
|
* <code>null</code>.
|
|
*
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input
|
|
* starts
|
|
* @param inputLen the input length
|
|
* @return the new buffer with the result, or null if the underlying
|
|
* cipher is a block cipher and the input data is too short to result in a
|
|
* new block.
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
*/
|
|
public final byte[] update(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen)
|
|
throws IllegalStateException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
if (inputLen == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return cipherSpi.engineUpdate(input, inputOffset, inputLen);
|
|
}
|
|
|
|
/**
|
|
* Continues a multiple-part encryption or decryption operation
|
|
* (depending on how this cipher was initialized), processing another data
|
|
* part.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, are processed,
|
|
* and the result is stored in the <code>output</code> buffer.
|
|
* <p>
|
|
* If the <code>output</code> buffer is too small to hold the result,
|
|
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
|
|
* call with a larger output buffer. Use
|
|
* <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big
|
|
* the output buffer should be.
|
|
* <p>
|
|
* If <code>inputLen</code> is zero, this method returns
|
|
* a length of zero.
|
|
*
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input starts
|
|
* @param inputLen the input length
|
|
* @param output the buffer for the result
|
|
* @return the number of bytes stored in <code>output</code>
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception ShortBufferException if the given output buffer is too small
|
|
* to hold the result
|
|
*/
|
|
public final int update(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen,
|
|
byte[] output)
|
|
throws IllegalStateException, ShortBufferException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
if (output == null)
|
|
{
|
|
throw new IllegalArgumentException("Null output passed");
|
|
}
|
|
|
|
if (inputLen == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, 0);
|
|
}
|
|
|
|
/**
|
|
* Continues a multiple-part encryption or decryption operation
|
|
* (depending on how this cipher was initialized), processing another data
|
|
* part.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, are processed,
|
|
* and the result is stored in the <code>output</code> buffer, starting at
|
|
* <code>outputOffset</code> inclusive.
|
|
* <p>
|
|
* If the <code>output</code> buffer is too small to hold the result,
|
|
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
|
|
* call with a larger output buffer. Use
|
|
* <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big
|
|
* the output buffer should be.
|
|
* <p>
|
|
* If <code>inputLen</code> is zero, this method returns
|
|
* a length of zero.
|
|
*
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input starts
|
|
* @param inputLen the input length
|
|
* @param output the buffer for the result
|
|
* @param outputOffset the offset in <code>output</code> where the result
|
|
* is stored
|
|
* @return the number of bytes stored in <code>output</code>
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception ShortBufferException if the given output buffer is too small
|
|
* to hold the result
|
|
*/
|
|
public final int update(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen,
|
|
byte[] output,
|
|
int outputOffset)
|
|
throws IllegalStateException, ShortBufferException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
if (output == null)
|
|
{
|
|
throw new IllegalArgumentException("Null output passed");
|
|
}
|
|
|
|
if (outputOffset < 0 || outputOffset >= output.length)
|
|
{
|
|
throw new IllegalArgumentException("Bad outputOffset");
|
|
}
|
|
|
|
if (inputLen == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, outputOffset);
|
|
}
|
|
|
|
/**
|
|
* Finishes a multiple-part encryption or decryption operation, depending
|
|
* on how this cipher was initialized.
|
|
* <p>
|
|
* Input data that may have been buffered during a previous
|
|
* <code>update</code> operation is processed, with padding (if requested)
|
|
* being applied.
|
|
* The result is stored in a new buffer.
|
|
* <p>
|
|
* A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
* @return the new buffer with the result
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final byte[] doFinal()
|
|
throws java.lang.IllegalStateException, IllegalBlockSizeException,
|
|
BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(null, 0, 0);
|
|
}
|
|
|
|
/**
|
|
* Finishes a multiple-part encryption or decryption operation, depending
|
|
* on how this cipher was initialized.
|
|
* <p>
|
|
* Input data that may have been buffered during a previous
|
|
* <code>update</code> operation is processed, with padding (if requested)
|
|
* being applied.
|
|
* The result is stored in the <code>output</code> buffer, starting at
|
|
* <code>outputOffset</code> inclusive.
|
|
* <p>
|
|
* If the <code>output</code> buffer is too small to hold the result,
|
|
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
|
|
* call with a larger output buffer. Use
|
|
* <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big
|
|
* the output buffer should be.
|
|
* <p>
|
|
* A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
*
|
|
* @param output the buffer for the result
|
|
* @param outputOffset the offset in <code>output</code> where the result
|
|
* is stored
|
|
* @return the number of bytes stored in <code>output</code>
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception ShortBufferException if the given output buffer is too small
|
|
* to hold the result
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final int doFinal(
|
|
byte[] output,
|
|
int outputOffset)
|
|
throws IllegalStateException, IllegalBlockSizeException,
|
|
ShortBufferException, BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (output == null)
|
|
{
|
|
throw new IllegalArgumentException("Null output passed");
|
|
}
|
|
|
|
if (outputOffset < 0 || outputOffset >= output.length)
|
|
{
|
|
throw new IllegalArgumentException("Bad outputOffset");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(null, 0, 0, output, outputOffset);
|
|
}
|
|
|
|
/**
|
|
* Encrypts or decrypts data in a single-part operation, or finishes a
|
|
* multiple-part operation. The data is encrypted or decrypted,
|
|
* depending on how this cipher was initialized.
|
|
* <p>
|
|
* The bytes in the <code>input</code> buffer, and any input bytes that
|
|
* may have been buffered during a previous <code>update</code> operation,
|
|
* are processed, with padding (if requested) being applied.
|
|
* The result is stored in a new buffer.
|
|
* <p>
|
|
* A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
*
|
|
* @param input the input buffer
|
|
* @return the new buffer with the result
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final byte[] doFinal(
|
|
byte[] input)
|
|
throws java.lang.IllegalStateException, IllegalBlockSizeException, BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(input, 0, input.length);
|
|
}
|
|
|
|
/**
|
|
* Encrypts or decrypts data in a single-part operation, or finishes a
|
|
* multiple-part operation. The data is encrypted or decrypted,
|
|
* depending on how this cipher was initialized.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, and any input
|
|
* bytes that may have been buffered during a previous <code>update</code>
|
|
* operation, are processed, with padding (if requested) being applied.
|
|
* The result is stored in a new buffer.
|
|
* <p>A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
*
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input starts
|
|
* @param inputLen the input length
|
|
* @return the new buffer with the result
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final byte[] doFinal(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen)
|
|
throws IllegalStateException, IllegalBlockSizeException, BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(input, inputOffset, inputLen);
|
|
}
|
|
|
|
/**
|
|
* Encrypts or decrypts data in a single-part operation, or finishes a
|
|
* multiple-part operation. The data is encrypted or decrypted,
|
|
* depending on how this cipher was initialized.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, and any input
|
|
* bytes that may have been buffered during a previous <code>update</code>
|
|
* operation, are processed, with padding (if requested) being applied.
|
|
* The result is stored in the <code>output</code> buffer.
|
|
* <p>
|
|
* If the <code>output</code> buffer is too small to hold the result,
|
|
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
|
|
* call with a larger output buffer. Use
|
|
* <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big
|
|
* the output buffer should be.
|
|
* <p>
|
|
* A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input starts
|
|
* @param inputLen the input length
|
|
* @param output the buffer for the result
|
|
* @return the number of bytes stored in <code>output</code>
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception ShortBufferException if the given output buffer is too small
|
|
* to hold the result
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final int doFinal(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen,
|
|
byte[] output)
|
|
throws IllegalStateException, ShortBufferException,
|
|
IllegalBlockSizeException, BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
if (output == null)
|
|
{
|
|
throw new IllegalArgumentException("Null output passed");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, 0);
|
|
}
|
|
|
|
/**
|
|
* Encrypts or decrypts data in a single-part operation, or finishes a
|
|
* multiple-part operation. The data is encrypted or decrypted,
|
|
* depending on how this cipher was initialized.
|
|
* <p>
|
|
* The first <code>inputLen</code> bytes in the <code>input</code>
|
|
* buffer, starting at <code>inputOffset</code> inclusive, and any input
|
|
* bytes that may have been buffered during a previous
|
|
* <code>update</code> operation, are processed, with padding
|
|
* (if requested) being applied.
|
|
* The result is stored in the <code>output</code> buffer, starting at
|
|
* <code>outputOffset</code> inclusive.
|
|
* <p>
|
|
* If the <code>output</code> buffer is too small to hold the result,
|
|
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
|
|
* call with a larger output buffer. Use
|
|
* <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big
|
|
* the output buffer should be.
|
|
* <p>
|
|
* A call to this method resets this cipher object to the state
|
|
* it was in when previously initialized via a call to <code>init</code>.
|
|
* That is, the object is reset and available to encrypt or decrypt
|
|
* (depending on the operation mode that was specified in the call to
|
|
* <code>init</code>) more data.
|
|
*
|
|
* @param input the input buffer
|
|
* @param inputOffset the offset in <code>input</code> where the input starts
|
|
* @param inputLen the input length
|
|
* @param output the buffer for the result
|
|
* @param outputOffset the offset in <code>output</code> where the result is
|
|
* stored
|
|
* @return the number of bytes stored in <code>output</code>
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized)
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
|
* no padding has been requested (only in encryption mode), and the total
|
|
* input length of the data processed by this cipher is not a multiple of
|
|
* block size
|
|
* @exception ShortBufferException if the given output buffer is too small
|
|
* to hold the result
|
|
* @exception BadPaddingException if this cipher is in decryption mode,
|
|
* and (un)padding has been requested, but the decrypted data is not
|
|
* bounded by the appropriate padding bytes
|
|
*/
|
|
public final int doFinal(
|
|
byte[] input,
|
|
int inputOffset,
|
|
int inputLen,
|
|
byte[] output,
|
|
int outputOffset)
|
|
throws IllegalStateException, ShortBufferException,
|
|
IllegalBlockSizeException, BadPaddingException
|
|
{
|
|
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is uninitialised");
|
|
}
|
|
|
|
if (input == null)
|
|
{
|
|
throw new IllegalArgumentException("Null input passed");
|
|
}
|
|
|
|
if (inputLen < 0 || inputOffset < 0
|
|
|| inputLen > (input.length - inputOffset))
|
|
{
|
|
throw new IllegalArgumentException("Bad inputOffset/inputLen");
|
|
}
|
|
|
|
if (output == null)
|
|
{
|
|
throw new IllegalArgumentException("Null output passed");
|
|
}
|
|
|
|
if (outputOffset < 0 || outputOffset >= output.length)
|
|
{
|
|
throw new IllegalArgumentException("Bad outputOffset");
|
|
}
|
|
|
|
return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, outputOffset);
|
|
}
|
|
|
|
/**
|
|
* Wrap a key.
|
|
*
|
|
* @param key the key to be wrapped.
|
|
* @return the wrapped key.
|
|
* @exception IllegalStateException if this cipher is in a wrong state (e.g., has not
|
|
* been initialized).
|
|
* @exception IllegalBlockSizeException if this cipher is a block cipher, no padding
|
|
* has been requested, and the length of the encoding of the key to be wrapped is not a
|
|
* multiple of the block size.
|
|
* @exception <DD>java.security.InvalidKeyException - if it is impossible or unsafe to
|
|
* wrap the key with this cipher (e.g., a hardware protected key is being passed to a
|
|
* software-only cipher).
|
|
*/
|
|
public final byte[] wrap(
|
|
Key key)
|
|
throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException
|
|
{
|
|
if (mode != WRAP_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is not initialised for wrapping");
|
|
}
|
|
|
|
if (key == null)
|
|
{
|
|
throw new IllegalArgumentException("Null key passed");
|
|
}
|
|
|
|
return cipherSpi.engineWrap(key);
|
|
}
|
|
|
|
/**
|
|
* Unwrap a previously wrapped key.
|
|
*
|
|
* @param wrappedKey the key to be unwrapped.
|
|
* @param wrappedKeyAlgorithm the algorithm associated with the wrapped key.
|
|
* @param wrappedKeyType the type of the wrapped key. This must be one of
|
|
* <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or <code>PUBLIC_KEY</code>.
|
|
* @return the unwrapped key.
|
|
* @exception IllegalStateException if this cipher is in a wrong state
|
|
* (e.g., has not been initialized).
|
|
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
|
* represent a wrapped key, or if the algorithm associated with the
|
|
* wrapped key is different from <code>wrappedKeyAlgorithm</code>
|
|
* and/or its key type is different from <code>wrappedKeyType</code>.
|
|
* @exception NoSuchAlgorithmException - if no installed providers
|
|
* can create keys for the <code>wrappedKeyAlgorithm</code>.
|
|
*/
|
|
public final Key unwrap(
|
|
byte[] wrappedKey,
|
|
String wrappedKeyAlgorithm,
|
|
int wrappedKeyType)
|
|
throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException
|
|
{
|
|
if (mode != UNWRAP_MODE)
|
|
{
|
|
throw new IllegalStateException("Cipher is not initialised for unwrapping");
|
|
}
|
|
|
|
if (wrappedKeyType != SECRET_KEY && wrappedKeyType != PUBLIC_KEY
|
|
&& wrappedKeyType != PRIVATE_KEY)
|
|
{
|
|
throw new IllegalArgumentException("Invalid key type argument");
|
|
}
|
|
|
|
if (wrappedKey == null)
|
|
{
|
|
throw new IllegalArgumentException("Null wrappedKey passed");
|
|
}
|
|
|
|
if (wrappedKeyAlgorithm == null)
|
|
{
|
|
throw new IllegalArgumentException("Null wrappedKeyAlgorithm string passed");
|
|
}
|
|
|
|
return cipherSpi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
|
|
}
|
|
}
|