public class GCMParameters
extends java.security.AlgorithmParametersSpi
GCMParameters ::= SEQUENCE {
aes-nonce OCTET STRING, -- recommended size is 12 octets
aes-ICVlen AES-GCM-ICVlen DEFAULT 12 }
AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16)
The aes-ICVLen specifies the length of the message authentication code value.
As stated in the NIST Special Publication 800-38D also the MAC length of 4 and 8 bytes are possible. Additionally, this class holds the GCM parameter associated data and MAC block.
GCMParameters can be generated by calling one of the AlgorithmParameters.getInstance
methods. Subsequently, the new AlgorithmParameters object must be initialized with
a proper parameter specification (class GCMParameterSpec is recommended) or a DER encoded byte array, e.g.
GCMParameterSpec gcmParamSpec = ...;
AlgorithmParameters params = AlgorithmParameters.getInstance("GCM", "IAIK");
params.init(gcmParamsSpec);
The GCMParameters can also be initialized with an IvParameterSpec object. In this case, the specified IV
will be used as nonce.
GCMParameterSpec,
AlgorithmParametersSpi| Constructor and Description |
|---|
GCMParameters()
The default constructor.
|
GCMParameters(byte[] aad,
byte[] nonce,
byte[] macBlock,
int macLength)
Creates GCM Parameters with the given additional data, IV, MAC length and MAC block.
|
| Modifier and Type | Method and Description |
|---|---|
static void |
checkKeyAndNonceReuse(boolean check)
Dis/Enables check for key/nonce reuse.
|
static void |
disableJava7ApiSupport(boolean disable)
Disables support for Java7 GCM API.
|
protected byte[] |
engineGetEncoded()
Returns the parameters as DER byte array.
|
protected byte[] |
engineGetEncoded(java.lang.String format)
Returns the parameters as a DER byte array.
|
protected java.security.spec.AlgorithmParameterSpec |
engineGetParameterSpec(java.lang.Class paramSpec)
Returns a GCM Parameter Specification of this GCM Parameters object.
|
protected void |
engineInit(java.security.spec.AlgorithmParameterSpec paramSpec)
Initializes this parameters object using the parameters specified in
paramSpec. |
protected void |
engineInit(byte[] params)
Initializes this GCMParameters object from the given DER encoded byte array.
|
protected void |
engineInit(byte[] params,
java.lang.String format)
Inits the parameters from an DER encoded byte array.
|
protected java.lang.String |
engineToString()
Returns a formatted string describing the GCM Parameters.
|
static void |
setIncludeDefaultMacLengthInEncding(boolean include)
Decides whether the aes-ICVlen (macLength) component should be
included when encoding GCM parameters if it has the default value (12).
|
static void |
setUseJava7ApiByDefault(boolean useJava7Api)
Decides whether to use the Java7 GCM API also when the Cipher has not been initialized with
a
javax.crypto.spec.GCMParameterSpec and no additional authenticated data (AAD)
has been specified by Cipher.updateAAD() call(s). |
public GCMParameters()
throws java.security.InvalidAlgorithmParameterException
AlgorithmParameters.getInstance for obtaining a GCMParameters object.java.security.InvalidAlgorithmParameterException - if the parameter values are incorrectpublic GCMParameters(byte[] aad,
byte[] nonce,
byte[] macBlock,
int macLength)
throws java.security.InvalidAlgorithmParameterException
aad - the additional data that is authenticatednonce - the nonce to generate the IVmacLength - number of bytes used for authenticationmacBlock - the authentication blockjava.security.InvalidAlgorithmParameterException - if the parameter values are incorrectpublic static void setIncludeDefaultMacLengthInEncding(boolean include)
include - whether to include a default macLength value (12)
when encoding GCM parameters or not (by default the
default value is not included)public static void disableJava7ApiSupport(boolean disable)
With the IAIK provider GCM maybe used in two alternative ways: with the IAIK GCM API
(where an iaik.security.cipher.GCMParameterSpec object has to be used to
specify any additional authenticated data (AAD) and the mac value is returned with the
GCM parameters) or with the Java7 API (where the additional authenticated data (AAD)
has to be specified by Cipher.updateAAD() call(s) and the mac value is
appended to the cipher text). The IAIK provider (version 5.4 or later) supports both APIs,
but when decrypting a cipher text the same API shall be used that has been used to create
the create the cipher text, i.e. the API usages shall not be mixed.
By default (without specific initialization) the IAIK GCM API is used (with a default tag
length value of 12 bytes and a random 12 byte nonce value). When initializing the Cipher
with a javax.crypto.spec.GCMParameterSpec or using Cipher method updateAAD()
to specify additional authenticated data (AAD) the IAIK GCM Cipher automatically
switches to the Java7 GCM API (using a default tag length of 16 bytes and a default 12
byte nonce value) and appending the mac value to the cipher text.
With this disableJava7ApiSupport you can disable Java7 GCM API support to ensure
to use only the IAIK GCM API. Alternatively Java7 GCM API support may be disabled
by using the "iaikjce.disableJava7GCMApiSupport" system property, e.g.:
java -Diaikjce.disableJava7GCMApiSupport=true MyGCMApp
disable - true to disable Java7 GCM API support, false
(default) to enable Java7 GCM API supportpublic static void setUseJava7ApiByDefault(boolean useJava7Api)
javax.crypto.spec.GCMParameterSpec and no additional authenticated data (AAD)
has been specified by Cipher.updateAAD() call(s).
With the IAIK provider GCM maybe used in two alternative ways: with the IAIK GCM API
(where an iaik.security.cipher.GCMParameterSpec object has to be used to
specify any additional authenticated data (AAD) and the mac value is returned with the
GCM parameters) or with the Java7 API (where the additional authenticated data (AAD)
has to be specified by Cipher.updateAAD() call(s) and the mac value is
appended to the cipher text). The IAIK provider (version 5.4 or later) supports both APIs,
but when decrypting a cipher text the same API shall be used that has been used to create
the create the cipher text, i.e. the API usages shall not be mixed.
By default (without specific initialization) the IAIK GCM API is used (with a default tag
length value of 12 bytes and a random 12 byte nonce value). When initializing the Cipher
with a javax.crypto.spec.GCMParameterSpec or using Cipher method updateAAD()
to specify additional authenticated data (AAD) the IAIK GCM Cipher automatically
switches to the Java7 GCM API (using a default tag length of 16 bytes and a default 12
byte nonce value) and appending the mac value to the cipher text. When calling this
setUseJava7ApiByDefault method the Java7 GCM API is used by default
(also when not initializing the Cipher with an AlgorithmParameterSpec or not calling updateAAD()<9.
useJava7Api - true to use the Java7 GCM API by default, false
(default) to use the IAIK GCM API by defaultpublic static void checkKeyAndNonceReuse(boolean check)
GCM shall not be used with same key and nonce multiple times. We cannot check any
key/nonce pair that may have been used in the past, but we can check if a Cipher
has been reinitialized before used for encryption a second time.
This means we only check if Cipher.init() has been called before
any further Cipher.update() or Cipher.doFinal() after
an encryption operation has been finished; we do not check if an Cipher.init()
call has actually provided a new key/nonce combination.
check - true to enable key/nonce reuse check (default), false
to disable itprotected byte[] engineGetEncoded()
throws java.io.IOException
engineGetEncoded in class java.security.AlgorithmParametersSpijava.io.IOException - if an encoding error occursprotected byte[] engineGetEncoded(java.lang.String format)
throws java.io.IOException
Format is ignored. Only DER encoding is supported at this time. This method
only calls engineGetEncoded(), regardless of what
is specified in the format string.
engineGetEncoded in class java.security.AlgorithmParametersSpiformat - the encoding format; ignoredjava.io.IOException - if an encoding error occursprotected java.security.spec.AlgorithmParameterSpec engineGetParameterSpec(java.lang.Class paramSpec)
throws java.security.spec.InvalidParameterSpecException
paramSpec
identifies the specification class in which the parameters should be returned, which might be
iaik.security.cipher.GCMParameterSpec or javax.crypto.spec.GCMParameterSpec.
Since GCM support has not been been introduced before Java7 javax.crypto.spec.GCMParameterSpec
can only be used with Java 7 or later.
iaik.security.cipher.GCMParameterSpec) have to be used to specify any
additional authenticated data (AAD); the Java7 API has added the updateAAD method
to the Cipher engine class for specifying additional authenticated data. The
IAIK API returns the mac value with the GCM parameters, the Java7 API appends the mac value
to the cipher text. For that reason the IAIK API and Java7 are not fully compatible (different
parameters and AAD handling, different mac handling). For instance, when decrypting/verifiying
an IAIK GCM encrypted message with the Java7 API the mac value has to be got from the GCMParameters
and appended to the cipher text. For that reason IAIK API usage should not be mixed with
Java7 API using.
However, the IAIK provider (version 5.4 or later) also supports the Java7 API when initializing
the Cipher with javax.crypto.spec.GCMParameterSpec parameters and using method
updateAAD for providing the additional authenticated data (AAD), e.g.:
// the cipher key
KeyGenerator kg = KeyGenerator.getInstance("AES", "IAIK");
SecretKey key = kg.generateKey();
// specify mac length (in bits) and nonce
int macLen = 128;
byte[] nonce = new byte[12];
random.nextBytes(nonce);
javax.crypto.spec.GCMParameterSpec paramSpec = new javax.crypto.spec.GCMParameterSpec(macLen, nonce);
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
// specify any AAD
byte[] aad = ...;
cipher.updateAAD(aad);
// encrypt
byte[] plainText = ...;
byte[] cipherText = cipher.doFinal(plainText);
For decrypting the Cipher is initialized with same key and parameters and the AAD again
has to be specified by calling updateAAD before calling any update
or doFinal method:
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.DECRYPT_MODE, key, paramSpec);
// specify any AAD
byte[] aad = ...;
cipher.updateAAD(aad);
// decrypt
byte[] plainText = cipher.doFinal(cipherText);
With the IAIK API the AAD value has to be specified via IAIK GCM parameters:
// the cipher key
KeyGenerator kg = KeyGenerator.getInstance("AES", "IAIK");
SecretKey key = kg.generateKey();
// specify mac length (in bytes), nonce and AAD
int macLen = 16;
byte[] nonce = new byte[12];
random.nextBytes(nonce);
byte[] aad = ...;
iaik.security.cipher.GCMParameterSpec paramSpec =
new iaik.security.cipher.GCMParameterSpec(aad, nonce, macLen);
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
// encrypt
byte[] plainText = ...;
byte[] cipherText = cipher.doFinal(plainText);
// get GCM parameters containing the MAC value
AlgorithmParameters params = cipher.getParameters();
For decrypting the Cipher is initialized with same key and the parameters (containing
the mac value) got from the encryption Cipher object:
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.DECRYPT_MODE, myKey, params);
// decrypt
byte[] plainText = cipher.doFinal(cipherText);
If you want to be assure that only the IAIK GCM API is used (to do not mix the API usage)
you can disable Java7 API support by calling method disableJava7APISupport:
GCMParameters.disableJava7ApiSupport(true);In this case method
getParameterSpec will throw an InvalidParameterSpecException
when trying to get a javax.crypto.spec.GCMParameterSpec.engineGetParameterSpec in class java.security.AlgorithmParametersSpiparamSpec - the specification class in which the parameters should be returned
- has to be class iaik.security.cipher.GCMParameterSpec
or (Java7 or later) class javax.crypto.spec.GCMParameterSpecjava.security.spec.InvalidParameterSpecException - if the requested parameter specification is inappropriate
for this parameter object.protected void engineInit(java.security.spec.AlgorithmParameterSpec paramSpec)
throws java.security.spec.InvalidParameterSpecException
paramSpec.
paramSpec might specify class iaik.security.cipher.GCMParameterSpec
or class javax.crypto.spec.GCMParameterSpec.
Since GCM support has not been been introduced before Java7 javax.crypto.spec.GCMParameterSpec
can only be used with Java 7 or later.
iaik.security.cipher.GCMParameterSpec) have to be used to specify any
additional authenticated data (AAD); the Java7 API has added the updateAAD method
to the Cipher engine class for specifying additional authenticated data. The
IAIK API returns the mac value with the GCM parameters, the Java7 API appends the mac value
to the cipher text. For that reason the IAIK API and Java7 are not fully compatible (different
parameters and AAD handling, different mac handling). For instance, when decrypting/verifiying
an IAIK GCM encrypted message with the Java7 API the mac value has to be got from the GCMParameters
and appended to the cipher text. For that reason IAIK API usage should not be mixed with
Java7 API using.
However, the IAIK provider (version 5.4 or later) also supports the Java7 API when initializing
the Cipher with javax.crypto.spec.GCMParameterSpec parameters and using method
updateAAD for providing the additional authenticated data (AAD), e.g.:
// the cipher key
KeyGenerator kg = KeyGenerator.getInstance("AES", "IAIK");
SecretKey key = kg.generateKey();
// specify mac length (in bits) and nonce
int macLen = 128;
byte[] nonce = new byte[12];
random.nextBytes(nonce);
javax.crypto.spec.GCMParameterSpec paramSpec = new javax.crypto.spec.GCMParameterSpec(macLen, nonce);
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
// specify any AAD
byte[] aad = ...;
cipher.updateAAD(aad);
// encrypt
byte[] plainText = ...;
byte[] cipherText = cipher.doFinal(plainText);
For decrypting the Cipher is initialized with same key and parameters and the AAD again
has to be specified by calling updateAAD before calling any update
or doFinal method:
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.DECRYPT_MODE, key, paramSpec);
// specify any AAD
byte[] aad = ...;
cipher.updateAAD(aad);
// decrypt
byte[] plainText = cipher.doFinal(cipherText);
With the IAIK API the AAD value has to be specified via IAIK GCM parameters:
// the cipher key
KeyGenerator kg = KeyGenerator.getInstance("AES", "IAIK");
SecretKey key = kg.generateKey();
// specify mac length (in bytes), nonce and AAD
int macLen = 16;
byte[] nonce = new byte[12];
random.nextBytes(nonce);
byte[] aad = ...;
iaik.security.cipher.GCMParameterSpec paramSpec =
new iaik.security.cipher.GCMParameterSpec(aad, nonce, macLen);
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
// encrypt
byte[] plainText = ...;
byte[] cipherText = cipher.doFinal(plainText);
// get GCM parameters containing the MAC value
AlgorithmParameters params = cipher.getParameters();
For decrypting the Cipher is initialized with same key and the parameters (containing
the mac value) got from the encryption Cipher object:
// create and init Cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "IAIK");
c.init(Cipher.DECRYPT_MODE, myKey, params);
// decrypt
byte[] plainText = cipher.doFinal(cipherText);
If you want to be assure that only the IAIK GCM API is used (to do not mix the API usage)
you can disable Java7 API support by calling method disableJava7APISupport:
GCMParameters.disableJava7ApiSupport(true);In this case method
init will throw an InvalidParameterSpecException
when trying to init the GCM parameters with a javax.crypto.spec.GCMParameterSpec.engineInit in class java.security.AlgorithmParametersSpiparamSpec - the parameter specification - must be GCMParameterSpec.java.security.spec.InvalidParameterSpecException - if the given parameter specification is
inappropriate for the initialization of this parameter object.protected void engineInit(byte[] params)
throws java.io.IOException
engineInit in class java.security.AlgorithmParametersSpiparams - the DER encoded byte arrayjava.io.IOException - if an error occurs when decoding the given byte array or
the derived parameter values are invalidprotected void engineInit(byte[] params,
java.lang.String format)
throws java.io.IOException
engineInit(params) for initializing this GCMParameters
object from the given DER encoded byte array, regardless of what is specified
in the format string.
engineInit in class java.security.AlgorithmParametersSpiparams - the DER encoded byte arrayformat - the encoding format; ignoredjava.io.IOException - if an error occurs when decoding the given byte arrayprotected java.lang.String engineToString()
engineToString in class java.security.AlgorithmParametersSpi