All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.com.ionic.sdk.cipher.aes.AesCtrCipher Maven / Gradle / Ivy

Go to download

The Ionic Java SDK provides an easy-to-use interface to the Ionic Platform.

There is a newer version: 2.9.0
Show newest version
package com.ionic.sdk.cipher.aes;

import com.ionic.sdk.agent.AgentSdk;
import com.ionic.sdk.core.codec.Transcoder;
import com.ionic.sdk.core.rng.CryptoRng;
import com.ionic.sdk.error.IonicException;
import com.ionic.sdk.error.SdkData;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * Ionic Machina Tools cipher implementation wrapping JCE-provided AES-CTR algorithm.  This cipher object
 * implements AES CTR mode encryption / decryption.
 * 

* AES-CTR (Counter Mode) is a streaming cipher variant of AES where the next key stream block is calculated by * encrypting increasing values of a "counter". *

* Class API variants are available to encrypt input strings into either raw byte arrays, or into the * base64-encoded string representation of a raw byte array. *

* Sample: *

 * public final void testAesCtrCipher_EncryptDecryptStringToBytes() throws IonicException {
 *     final KeyServices keyServices = IonicTestEnvironment.getInstance().getKeyServices();
 *     final CreateKeysResponse.Key key = keyServices.createKey().getFirstKey();
 *     final String plainText = "Hello, Machina!";
 *     final AesCtrCipher cipher = new AesCtrCipher();
 *     cipher.setKey(key.getSecretKey());
 *     final byte[] cipherText = cipher.encryptString(plainText);
 *     final String plainTextRecover = cipher.decryptToString(cipherText);
 *     Assert.assertEquals(plainText, plainTextRecover);
 * }
 * 
*

* Sample: *

 * public final void testAesCtrCipher_EncryptDecryptStringToString() throws IonicException {
 *     final KeyServices keyServices = IonicTestEnvironment.getInstance().getKeyServices();
 *     final CreateKeysResponse.Key key = keyServices.createKey().getFirstKey();
 *     final String plainText = "Hello, Machina!";
 *     final AesCipherAbstract cipher = new AesCtrCipher();
 *     cipher.setKey(key.getSecretKey());
 *     final String cipherText = cipher.encryptToBase64(plainText);
 *     final String plainTextRecover = cipher.decryptBase64ToString(cipherText);
 *     Assert.assertEquals(plainText, plainTextRecover);
 * }
 * 
*

* See Machina Developers for * more information on this cryptography implementation. */ public class AesCtrCipher extends AesCipherAbstract { /** * ID for AesCtrCipher class cipher. */ private static final String ID = "aes_ctr"; /** * Label for AesCtrCipher class cipher. */ private static final String LABEL = "AES CTR Cipher"; /** * Construct an instance of an Ionic AES CTR-mode cipher. * * @throws IonicException on cryptography errors */ public AesCtrCipher() throws IonicException { this((byte[]) null); } /** * Construct an instance of an Ionic AES CTR-mode cipher. * * @param cipherKey the raw bytes of the key * @throws IonicException on cryptography errors */ public AesCtrCipher(final byte[] cipherKey) throws IonicException { super(getCipherInstance()); setKey(cipherKey); } /** * Construct an instance of an Ionic AES CTR-mode cipher. * * @param secretKey the JCE object representation of the key * @throws IonicException on cryptography errors */ public AesCtrCipher(final SecretKey secretKey) throws IonicException { super(getCipherInstance()); setKey(secretKey); } /** * Construct an instance of a Java cipher. * * @return the Cipher to be wrapped * @throws IonicException if Cipher cannot be instantiated */ private static Cipher getCipherInstance() throws IonicException { return AgentSdk.getCrypto().getCipherAesCtr(); } @Override public final String getId() { return ID; } @Override public final String getLabel() { return LABEL; } /** * Encrypt a byte array and return the result as another byte array. * * @param plainText array of bytes to encrypt * @return array of bytes representing the ciphertext * @throws IonicException on cryptography errors */ @Override public final byte[] encrypt(final byte[] plainText) throws IonicException { return encryptInternal(plainText); } /** * Encrypt a string and return the result as a byte array. * * @param plainText array of bytes to encrypt * @return array of bytes representing the ciphertext * @throws IonicException on cryptography errors */ @Override public final byte[] encrypt(final String plainText) throws IonicException { return encryptInternal(Transcoder.utf8().decode(plainText)); } /** * Encrypt a byte array and return the result as another byte array. * * @param plainText array of bytes to encrypt * @return array of bytes representing the ciphertext * @throws IonicException on cryptography errors, or invalid (null) parameters (plainText) */ private byte[] encryptInternal(final byte[] plainText) throws IonicException { SdkData.checkNotNull(plainText, ERR_LABEL); // cipher configuration final byte[] iv = new CryptoRng().rand(new byte[AesCipher.SIZE_IV]); final IvParameterSpec parameterSpec = new IvParameterSpec(iv); // encrypt final byte[] cipherText = super.encrypt(plainText, null, parameterSpec); // package result final byte[] cipherTextIonic = Arrays.copyOf(iv, (iv.length + cipherText.length)); System.arraycopy(cipherText, 0, cipherTextIonic, iv.length, cipherText.length); return cipherTextIonic; } /** * Encrypt a byte buffer. This API makes use of the JRE * {@link Cipher#doFinal(ByteBuffer, ByteBuffer)} API, which uses the parameter ByteBuffer * objects internally instead of allocating new buffers. * * @param plainText ByteBuffer containing bytes to encrypt * @param cipherText ByteBuffer to receive the result of the cryptography operation * @return the number of bytes stored in ciphertext * @throws IonicException on cryptography errors, or invalid (null) parameters (key, plainText) */ public final int encrypt(final ByteBuffer plainText, final ByteBuffer cipherText) throws IonicException { SdkData.checkNotNull(plainText, ERR_LABEL); SdkData.checkNotNull(cipherText, ERR_LABEL); // cipher configuration final byte[] iv = new CryptoRng().rand(new byte[AesCipher.SIZE_IV]); final IvParameterSpec parameterSpec = new IvParameterSpec(iv); // encrypt cipherText.clear(); cipherText.put(iv); return iv.length + super.encrypt(plainText, cipherText, null, parameterSpec); } /** * Encrypt a byte buffer. This API makes use of the JRE * {@link Cipher#doFinal(ByteBuffer, ByteBuffer)} API, which uses the parameter ByteBuffer * objects internally instead of allocating new buffers. * * @param plainText ByteBuffer containing bytes to encrypt * @param cipherText ByteBuffer to receive the result of the cryptography operation * @param parameterSpec additional cipher configuration * @return the number of bytes stored in ciphertext * @throws IonicException on cryptography errors, or invalid (null) parameters (key, plainText) */ public final int encrypt(final ByteBuffer plainText, final ByteBuffer cipherText, final IvParameterSpec parameterSpec) throws IonicException { SdkData.checkNotNull(plainText, ERR_LABEL); SdkData.checkNotNull(cipherText, ERR_LABEL); SdkData.checkNotNull(parameterSpec, ERR_LABEL); // encrypt cipherText.clear(); return super.encrypt(plainText, cipherText, null, parameterSpec); } /** * Decrypt a previously encrypted byte array and return the result as another byte array. * * @param cipherText array of bytes to decrypt * @return array of bytes representing the decrypted plaintext * @throws IonicException on cryptography errors, or invalid (null) parameters (cipherText) */ @Override public final byte[] decrypt(final byte[] cipherText) throws IonicException { SdkData.checkNotNull(cipherText, ERR_LABEL); // cipher configuration final IvParameterSpec parameterSpec = new IvParameterSpec(cipherText, 0, AesCipher.SIZE_IV); // decrypt return super.decrypt(cipherText, null, parameterSpec); } /** * Decrypt a previously encrypted byte buffer. This API makes use of the JRE * {@link Cipher#doFinal(ByteBuffer, ByteBuffer)} API, which uses the parameter ByteBuffer * objects internally instead of allocating new buffers. * * @param plainText ByteBuffer to receive the result of the cryptography operation * @param cipherText ByteBuffer containing bytes to decrypt * @return the number of bytes stored in plaintext * @throws IonicException on cryptography errors */ public final int decrypt(final ByteBuffer plainText, final ByteBuffer cipherText) throws IonicException { SdkData.checkNotNull(plainText, ERR_LABEL); SdkData.checkNotNull(cipherText, ERR_LABEL); final byte[] iv = new byte[AesCipher.SIZE_IV]; cipherText.get(iv); final IvParameterSpec parameterSpec = new IvParameterSpec(iv, 0, iv.length); plainText.clear(); return super.decrypt(plainText, cipherText, null, parameterSpec); } /** * Decrypt a previously encrypted byte buffer. This API makes use of the JRE * {@link Cipher#doFinal(ByteBuffer, ByteBuffer)} API, which uses the parameter ByteBuffer * objects internally instead of allocating new buffers. * * @param plainText ByteBuffer to receive the result of the cryptography operation * @param cipherText ByteBuffer containing bytes to decrypt * @param parameterSpec additional cipher configuration * @return the number of bytes stored in plaintext * @throws IonicException on cryptography errors */ public final int decrypt(final ByteBuffer plainText, final ByteBuffer cipherText, final IvParameterSpec parameterSpec) throws IonicException { SdkData.checkNotNull(plainText, ERR_LABEL); SdkData.checkNotNull(cipherText, ERR_LABEL); SdkData.checkNotNull(parameterSpec, ERR_LABEL); // decrypt plainText.clear(); return super.decrypt(plainText, cipherText, null, parameterSpec); } /** * Label for API call validity check failure. */ private static final String ERR_LABEL = AesCtrCipher.class.getSimpleName(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy