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.AlgorithmParametersSpi
java.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.AlgorithmParametersSpi
format
- 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.AlgorithmParametersSpi
paramSpec
- 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.GCMParameterSpec
java.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.AlgorithmParametersSpi
paramSpec
- 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.AlgorithmParametersSpi
params
- 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.AlgorithmParametersSpi
params
- 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