public class ChaCha20Poly1305
extends javax.crypto.CipherSpi
Cipher.getInstance
with the "ChaCha20Poly1305"
algorithm name to get a Cipher object for the ChaCha20Poly1305 cipher.
// generate key KeyGenerator keyGen = KeyGenerator.getInstance("ChaCha20Poly1305", "IAIK"); SecretKey secretKey = keyGen.generateKey(); // get Cipher and init it for encryption Cipher cipher = Cipher.getInstance("ChaCha20Poly1305", "IAIK"); Cipher.init(Cipher.ENCRYPT_MODE, secretKey); // add additional associated data (aad) if needed cipher.updateAAD(aaData); // encrypt data // Return value from doFinal is the plaintext concatenated with the MAC byte[] cipherTextWithTag = cipher.doFinal(data); // get the initialization vector from the cipher byte[] ivBytes = cipher.getIV(); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); // When decrypting the encrypted message the initialization vector has to be provided as parameter:Cipher cipher = Cipher.getInstance("ChaCha20Poly1305", "IAIK"); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec); // add additional associated data (aad) if present cipher.updateAAD(aaData); byte[] plaintext = cipher.doFinal(cipherTextWithTag);
By default the mac tag is appended to the cipher text. However,
when initializing a ChaCha20Poly1305 Cipher with a ChaCha20Poly1305CMSParameterSpec
for use with CMS (Cryptographic Message Syntax; see RFC 8103) the
mac tag is NOT appended to the cipher text and has to be got/set
from/for the Cipher by means of a ChaCha20Poly1305CMSParameterSpec
object, e.g.:
// generate key
KeyGenerator keyGenerator = KeyGenerator.getInstance("ChaCha20Poly1305", "IAIK");
SecretKey secretKey = keyGenerator.generateKey();
// the data to be encrypted
byte[] plaintext = ...;
// any additional associated data
byte[] aad = ...;
// create Cipher object
Cipher cipher = Cipher.getInstance("ChaCha20Poly1305/NONE/NoPadding", "IAIK");
// create the nonce value
byte[] nonce = new byte[12];
SecureRandom random = ...;
random.nextBytes(nonce);
// create ChaCha20Poly1305 CMS parameter spec
ChaCha20Poly1305CMSParameterSpec paramSpec = new ChaCha20Poly1305CMSParameterSpec(aad, nonce);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
// encrypt data
byte[] ciphertext = cipher.doFinal(plaintext);
// get algorithm parameters from Cipher object
AlgorithmParameters params = encryptionEngine.getParameters();
// get ChaCha20Poly1305CMSParameterSpec (including the mac from parameters)
ChaCha20Poly1305CMSParameterSpec spec =
(ChaCha20Poly1305CMSParameterSpec)params.getParameterSpec(ChaCha20Poly1305CMSParameterSpec.class);
byte[] mac = spec.getMac();
// decryption
Cipher cipher = Cipher.getInstance("ChaCha20Poly1305/NONE/NoPadding", "IAIK");
// init Cipher with ChaCha20Poly1305CMSParameterSpec containing the mac value
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
ChaCha20Poly1305Parameters
,
ChaCha20Poly1305ParameterSpec
,
ChaCha20Poly1305CMSParameterSpec
,
Cipher
Constructor and Description |
---|
ChaCha20Poly1305()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
byte[] |
engineDoFinal(byte[] in,
int inOff,
int inLen)
Returns the result of the last step of a multi-step en/decryption operation
or the result of a single-step en/decryption operation by processing the
given input data and any remaining buffered data.
|
int |
engineDoFinal(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
Performs the last step of a multi-step en/decryption operation or a
single-step en/decryption operation by processing the given input data and
any remaining buffered data.
|
int |
engineGetBlockSize()
Returns the block size corresponding to this cipher.
|
byte[] |
engineGetIV()
Returns a byte array containing the initialization vector (IV).
|
protected int |
engineGetKeySize(java.security.Key key) |
int |
engineGetOutputSize(int inLen)
Returns the output buffer size necessary for capturing the data resulting
from the next
update or doFinal operation
including any data currently being buffered. |
java.security.AlgorithmParameters |
engineGetParameters()
Gets the algorithm parameters used/generated by this Cipher engine.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.spec.AlgorithmParameterSpec params,
java.security.SecureRandom random)
Initializes this cipher object with proper key and algorithm parameter
values, and some random seed.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.AlgorithmParameters params,
java.security.SecureRandom random)
Initializes this cipher object with proper key and algorithm parameter
values, and some random seed.
|
void |
engineInit(int opmode,
java.security.Key key,
java.security.SecureRandom random)
Initializes this cipher object with a proper key and some random seed.
|
void |
engineSetMode(java.lang.String cipherMode)
Sets the mode of this cipher.
|
void |
engineSetPadding(java.lang.String paddingName)
Overrides method engineSetPadding from parent class since no padding is
required.
|
protected java.security.Key |
engineUnwrap(byte[] wrappedKey,
java.lang.String wrappedKeyAlgorithm,
int wrappedKeyType) |
byte[] |
engineUpdate(byte[] in,
int inOff,
int inLen)
This method is used to encrypt or decrypt chunks of data of any length.
|
int |
engineUpdate(byte[] in,
int inOff,
int inLen,
byte[] out,
int outOff)
This method is used to encrypt or decrypt chunks of data of any length.
|
protected void |
engineUpdateAAD(byte[] src,
int offset,
int len) |
protected byte[] |
engineWrap(java.security.Key key) |
int |
getModeBlockSize()
Returns the block size corresponding to the actual cipher mode.
|
java.lang.String |
toString()
Returns a string representation of this Cipher.
|
public ChaCha20Poly1305()
This constructor is only internally used for creating a ChaCha20Poly1305 Cipher.
Applications should not call this constructor to get a ChaCha20Poly1305 Cipher;
they should call one of the Cipher.getInstance
factory methods instead:
Cipher cipher = Cipher.getInstance("ChaCha20Poly1305/ECB/NoPadding", "IAIK");
Cipher.getInstance(java.lang.String)
public void engineSetPadding(java.lang.String paddingName) throws javax.crypto.NoSuchPaddingException
paddingName
- the name of the padding (ignored)javax.crypto.NoSuchPaddingException
- cannot occurCipherSpi.engineSetPadding(java.lang.String)
public void engineInit(int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
Before a cipher object is ready for data processing, it has to be
initialized according to the desired cryptographic operation, which is
specified by the opmode
parameter (either ENCRYPT_MODE or
DECCRYPT_MODE), e.g.:
cipher_obj.init(Cipher.ENCRYPT_MODE, key, alg_params, random_seed);
The Cipher init
will call the proper CipherSpi
engineInit
method.
engineInit
in class javax.crypto.CipherSpi
opmode
- the operation mode for which this cipher is used (ENCRYPT_MODE or
DECRYPT_MODE)key
- the keyparams
- the algorithm parametersrandom
- the random seedjava.security.InvalidKeyException
- if the given key cannot be used for initializing this cipherjava.security.InvalidAlgorithmParameterException
- if the given algorithm parameters don't match to this cipherCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public void engineInit(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException
Before a cipher object is ready for data processing, it has to be
initialized according to the desired cryptographic operation, which is
specified by the opmode
parameter (either ENCRYPT_MODE or
DECCRYPT_MODE), e.g.:
cipher_obj.init(Cipher.ENCRYPT_MODE, key, random_seed);
The Cipher init
will call the proper CipherSpi
engineInit
method.
If this cipher (including its underlying feedback or padding scheme) requires any random bytes, it will get them from random.
engineInit
in class javax.crypto.CipherSpi
opmode
- the operation mode for which this cipher is used (ENCRYPT_MODE or
DECRYPT_MODE)key
- the keyrandom
- the random seedjava.security.InvalidKeyException
- if the given key cannot be used for initializing this cipherCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public void engineInit(int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidKeyException, java.security.InvalidAlgorithmParameterException
Before a cipher object is ready for data processing, it has to be
initialized according to the desired cryptographic operation, which is
specified by the opmode
parameter (either ENCRYPT_MODE or
DECCRYPT_MODE), e.g.:
cipher_obj.init(Cipher.ENCRYPT_MODE, key, alg_params, random_seed);
The Cipher init
will call the proper CipherSpi
engineInit
method.
engineInit
in class javax.crypto.CipherSpi
opmode
- the operation mode for which this cipher is used (ENCRYPT_MODE or
DECRYPT_MODE)key
- the keyparams
- the algorithm parametersrandom
- the random seedjava.security.InvalidKeyException
- if the given key cannot be used for initializing this cipherjava.security.InvalidAlgorithmParameterException
- if the given algorithm parameters don't match to this cipherCipher.init(int, java.security.Key)
,
CipherSpi.engineInit(int, java.security.Key, java.security.SecureRandom)
public java.security.AlgorithmParameters engineGetParameters()
engineGetParameters
in class javax.crypto.CipherSpi
public void engineSetMode(java.lang.String cipherMode) throws java.security.NoSuchAlgorithmException
engineSetMode
in class javax.crypto.CipherSpi
cipherMode
- the cipher modejava.security.NoSuchAlgorithmException
- if this cipher mode is not supportedCipherSpi.engineSetMode(java.lang.String)
public byte[] engineUpdate(byte[] in, int inOff, int inLen)
doFinal()
method. This
method will automatically allocate an output buffer of the right size.engineUpdate
in class javax.crypto.CipherSpi
in
- the input data.inOff
- the offset indicating where the subarray starts in the
in
array.inLen
- the length of the subarray.BufferedCipher.engineDoFinal(byte[], int, int, byte[], int)
,
Cipher.doFinal()
,
Cipher.update(byte[])
,
CipherSpi.engineUpdate(byte[], int, int)
public int engineUpdate(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws javax.crypto.ShortBufferException
doFinal()
method.engineUpdate
in class javax.crypto.CipherSpi
in
- the input data.inOff
- the offset indicating where the subarray starts in the
in
array.inLen
- the length of the subarray.out
- the output buffer.outOff
- the offset indicating where to start writing the result into the
output buffer.out
array.javax.crypto.ShortBufferException
- if the buffer size is to shortBufferedCipher.engineDoFinal(byte[], int, int, byte[], int)
,
Cipher.doFinal()
,
Cipher.update(byte[])
,
CipherSpi.engineUpdate(byte[], int, int)
protected void engineUpdateAAD(byte[] src, int offset, int len)
engineUpdateAAD
in class javax.crypto.CipherSpi
public int engineGetOutputSize(int inLen)
update
or doFinal
operation
including any data currently being buffered.engineGetOutputSize
in class javax.crypto.CipherSpi
inLen
- the number of bytes to processCipher.getOutputSize(int)
,
CipherSpi.engineGetOutputSize(int)
public byte[] engineGetIV()
null
is returned.engineGetIV
in class javax.crypto.CipherSpi
null
otherwise.Cipher.getIV()
,
CipherSpi.engineGetIV()
public int getModeBlockSize()
public int engineGetBlockSize()
engineGetBlockSize
in class javax.crypto.CipherSpi
Cipher.getBlockSize()
,
CipherSpi.engineGetBlockSize()
public int engineDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff) throws javax.crypto.ShortBufferException, javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted, including any buffered bytes of a previous
update
operation. If necessary, padding is performed. The
result is stored in the given output byte array, beginning at
outputOffset
. The number of bytes stored in this byte array
are returned.
engineDoFinal
in class javax.crypto.CipherSpi
in
- the byte array holding the data to be processedinOff
- the offset indicating the start position within the input byte
arrayinLen
- the number of bytes to be processedout
- the byte array for holding the resultoutOff
- the offset indicating the start position within the output byte
array to which the en/decrypted data is writtenjavax.crypto.ShortBufferException
- if the given output buffer is too small for holding the resultjavax.crypto.IllegalBlockSizeException
- if the total length of the processed data is not a multiple of
the block size for a (no padding performing) block cipherjavax.crypto.BadPaddingException
- if the decrypted data is not bounded by the proper padding
bytes after data decryption including (un)paddingCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
public byte[] engineDoFinal(byte[] in, int inOff, int inLen) throws javax.crypto.IllegalBlockSizeException, javax.crypto.BadPaddingException
The data to be processed is given in an input byte array. Beginning at
inputOffset
, only the first inputLen
bytes are
en/decrypted, including any buffered bytes of a previous
update
operation. If necessary, padding is performed. The
result is returned as a output byte array.
engineDoFinal
in class javax.crypto.CipherSpi
in
- the byte array holding the data to be processedinOff
- the offset indicating the start position within the input byte
arrayinLen
- the number of bytes to be processedjavax.crypto.IllegalBlockSizeException
- if the total length of the processed data is not a multiple of
the block size for a (no padding performing) block cipherjavax.crypto.BadPaddingException
- if the decrypted data is not bounded by the proper padding
bytes after data decryption including (un)paddingCipher.doFinal()
,
CipherSpi.engineDoFinal(byte[], int, int)
public java.lang.String toString()
toString
in class java.lang.Object
protected int engineGetKeySize(java.security.Key key) throws java.security.InvalidKeyException
engineGetKeySize
in class javax.crypto.CipherSpi
java.security.InvalidKeyException
protected byte[] engineWrap(java.security.Key key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException
engineWrap
in class javax.crypto.CipherSpi
javax.crypto.IllegalBlockSizeException
java.security.InvalidKeyException
protected java.security.Key engineUnwrap(byte[] wrappedKey, java.lang.String wrappedKeyAlgorithm, int wrappedKeyType) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException
engineUnwrap
in class javax.crypto.CipherSpi
java.security.InvalidKeyException
java.security.NoSuchAlgorithmException