Search in sources :

Example 21 with GCMBlockCipher

use of org.bouncycastle.crypto.modes.GCMBlockCipher in project nem2-sdk-java by nemtech.

the class AESGCM method createAESGCMCipher.

/**
 * Creates a new AES/GCM/NoPadding cipher.
 *
 * @param secretKey The AES key. Must not be {@code null}.
 * @param forEncryption If {@code true} creates an encryption cipher, else creates a decryption
 *     cipher.
 * @param iv The initialisation vector (IV). Must not be {@code null}.
 * @return The AES/GCM/NoPadding cipher.
 */
private static GCMBlockCipher createAESGCMCipher(final byte[] secretKey, final boolean forEncryption, final byte[] iv) {
    // Initialise AES cipher
    BlockCipher cipher = createCipher(secretKey, forEncryption);
    // Create GCM cipher with AES
    GCMBlockCipher gcm = new GCMBlockCipher(cipher);
    final KeyParameter keyParam = new KeyParameter(secretKey);
    final CipherParameters params = new ParametersWithIV(keyParam, iv);
    gcm.init(forEncryption, params);
    return gcm;
}
Also used : CipherParameters(org.bouncycastle.crypto.CipherParameters) ParametersWithIV(org.bouncycastle.crypto.params.ParametersWithIV) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) BlockCipher(org.bouncycastle.crypto.BlockCipher) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 22 with GCMBlockCipher

use of org.bouncycastle.crypto.modes.GCMBlockCipher in project nem2-sdk-java by nemtech.

the class AESGCM method encrypt.

/**
 * Encrypts the specified plain text using AES/GCM/NoPadding.
 *
 * @param secretKey The AES key. Must not be {@code null}.
 * @param plainText The plain text. Must not be {@code null}.
 * @param iv The initialisation vector (IV). Must not be {@code null}.
 * @return The authenticated cipher text.
 * @throws CryptoException If encryption failed.
 */
public static AuthenticatedCipherText encrypt(final byte[] secretKey, final byte[] iv, final byte[] plainText) throws RuntimeException {
    // Initialise AES/GCM cipher for encryption
    GCMBlockCipher cipher = createAESGCMCipher(secretKey, true, iv);
    // Prepare output buffer
    int outputLength = cipher.getOutputSize(plainText.length);
    byte[] output = new byte[outputLength];
    // Produce cipher text
    int outputOffset = cipher.processBytes(plainText, 0, plainText.length, output, 0);
    // Produce authentication tag
    try {
        outputOffset += cipher.doFinal(output, outputOffset);
    } catch (InvalidCipherTextException e) {
        throw new CryptoException("Could Not Generate GCM Authentication: " + ExceptionUtils.getMessage(e), e);
    }
    // Split output into cipher text and authentication tag
    int authTagLength = AUTH_TAG_BIT_LENGTH / 8;
    byte[] cipherText = new byte[outputOffset - authTagLength];
    byte[] authTag = new byte[authTagLength];
    System.arraycopy(output, 0, cipherText, 0, cipherText.length);
    System.arraycopy(output, outputOffset - authTagLength, authTag, 0, authTag.length);
    return new AuthenticatedCipherText(cipherText, authTag, iv);
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) CryptoException(io.nem.symbol.core.crypto.CryptoException) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 23 with GCMBlockCipher

use of org.bouncycastle.crypto.modes.GCMBlockCipher in project nem2-sdk-java by nemtech.

the class AESGCM method decrypt.

/**
 * Decrypts the specified cipher text using AES/GCM/NoPadding.
 *
 * @param secretKey The AES key. Must not be {@code null}.
 * @param iv The initialisation vector (IV). Must not be {@code null}.
 * @param cipherText The cipher text. Must not be {@code null}.
 * @param authTag The authentication tag. Must not be {@code null}.
 * @return The decrypted plain text.
 * @throws CryptoException If decryption failed.
 */
public static byte[] decrypt(final byte[] secretKey, final byte[] iv, final byte[] cipherText, final byte[] authTag) throws RuntimeException {
    // Initialise AES/GCM cipher for decryption
    GCMBlockCipher cipher = createAESGCMCipher(secretKey, false, iv);
    // Join cipher text and authentication tag to produce cipher input
    byte[] input = new byte[cipherText.length + authTag.length];
    System.arraycopy(cipherText, 0, input, 0, cipherText.length);
    System.arraycopy(authTag, 0, input, cipherText.length, authTag.length);
    int outputLength = cipher.getOutputSize(input.length);
    byte[] output = new byte[outputLength];
    // Decrypt
    int outputOffset = cipher.processBytes(input, 0, input.length, output, 0);
    // Validate authentication tag
    try {
        outputOffset += cipher.doFinal(output, outputOffset);
    } catch (InvalidCipherTextException e) {
        throw new CryptoException("Could decrypt value: " + ExceptionUtils.getMessage(e), e);
    }
    return output;
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) CryptoException(io.nem.symbol.core.crypto.CryptoException) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 24 with GCMBlockCipher

use of org.bouncycastle.crypto.modes.GCMBlockCipher in project syncany by syncany.

the class AesGcmWithBcInputStreamTest method testE_BouncyCastleCipherInputStreamWithAesGcmLongPlaintext.

@Test
public void testE_BouncyCastleCipherInputStreamWithAesGcmLongPlaintext() throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
    // Encrypt (not interesting in this example)
    byte[] randomKey = createRandomArray(16);
    byte[] randomIv = createRandomArray(16);
    // <<<< 4080 bytes fails, 4079 bytes works!
    byte[] originalPlaintext = createRandomArray(4080);
    byte[] originalCiphertext = encryptWithAesGcm(originalPlaintext, randomKey, randomIv);
    // Decrypt with BouncyCastle implementation of CipherInputStream
    AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIv));
    try {
        readFromStream(new org.bouncycastle.crypto.io.CipherInputStream(new ByteArrayInputStream(originalCiphertext), cipher));
        // ^^^^^^^^^^^^^^^ INTERESTING PART ^^^^^^^^^^^^^^^^
        // 
        // In this example, the BouncyCastle implementation of the CipherInputStream throws an ArrayIndexOutOfBoundsException.
        // The only difference to the example above is that the plaintext is now 4080 bytes long! For 4079 bytes plaintexts,
        // everything works just fine.
        System.out.println("Test E: org.bouncycastle.crypto.io.CipherInputStream:        OK, throws no exception");
    } catch (IOException e) {
        fail("Test E: org.bouncycastle.crypto.io.CipherInputStream:        NOT OK throws: " + e.getMessage());
    }
}
Also used : AESEngine(org.bouncycastle.crypto.engines.AESEngine) AEADParameters(org.bouncycastle.crypto.params.AEADParameters) ByteArrayInputStream(java.io.ByteArrayInputStream) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) InvalidCipherTextIOException(org.bouncycastle.crypto.io.InvalidCipherTextIOException) IOException(java.io.IOException) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) AEADBlockCipher(org.bouncycastle.crypto.modes.AEADBlockCipher) Test(org.junit.Test)

Example 25 with GCMBlockCipher

use of org.bouncycastle.crypto.modes.GCMBlockCipher in project syncany by syncany.

the class AesGcmWithBcInputStreamTest method testD_BouncyCastleCipherInputStreamWithAesGcm.

@Test
public void testD_BouncyCastleCipherInputStreamWithAesGcm() throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
    // Encrypt (not interesting in this example)
    byte[] randomKey = createRandomArray(16);
    byte[] randomIv = createRandomArray(16);
    byte[] originalPlaintext = "Confirm 100$ pay".getBytes("ASCII");
    byte[] originalCiphertext = encryptWithAesGcm(originalPlaintext, randomKey, randomIv);
    // Attack / alter ciphertext (an attacker would do this!)
    byte[] alteredCiphertext = Arrays.clone(originalCiphertext);
    // <<< Change 100$ to 900$
    alteredCiphertext[8] = (byte) (alteredCiphertext[8] ^ 0x08);
    // Decrypt with BouncyCastle implementation of CipherInputStream
    AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIv));
    try {
        readFromStream(new org.bouncycastle.crypto.io.CipherInputStream(new ByteArrayInputStream(alteredCiphertext), cipher));
        // ^^^^^^^^^^^^^^^ INTERESTING PART ^^^^^^^^^^^^^^^^
        // 
        // The BouncyCastle implementation of the CipherInputStream detects MAC verification errors and
        // throws a InvalidCipherTextIOException if an error occurs. Nice! A more or less minor issue
        // however is that it is incompatible with the standard JCE Cipher class from the javax.crypto
        // package. The new interface AEADBlockCipher must be used. The code below is not executed.
        fail("Test D: org.bouncycastle.crypto.io.CipherInputStream:        NOT OK, tampering not detected");
    } catch (InvalidCipherTextIOException e) {
        System.out.println("Test D: org.bouncycastle.crypto.io.CipherInputStream:        OK, tampering detected");
    }
}
Also used : AESEngine(org.bouncycastle.crypto.engines.AESEngine) AEADParameters(org.bouncycastle.crypto.params.AEADParameters) ByteArrayInputStream(java.io.ByteArrayInputStream) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) AEADBlockCipher(org.bouncycastle.crypto.modes.AEADBlockCipher) InvalidCipherTextIOException(org.bouncycastle.crypto.io.InvalidCipherTextIOException) Test(org.junit.Test)

Aggregations

GCMBlockCipher (org.bouncycastle.crypto.modes.GCMBlockCipher)29 KeyParameter (org.bouncycastle.crypto.params.KeyParameter)22 AEADParameters (org.bouncycastle.crypto.params.AEADParameters)20 AESEngine (org.bouncycastle.crypto.engines.AESEngine)19 AEADBlockCipher (org.bouncycastle.crypto.modes.AEADBlockCipher)16 InvalidCipherTextException (org.bouncycastle.crypto.InvalidCipherTextException)6 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 IvParameterSpec (javax.crypto.spec.IvParameterSpec)5 SecretKeySpec (javax.crypto.spec.SecretKeySpec)5 CipherParameters (org.bouncycastle.crypto.CipherParameters)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 IOException (java.io.IOException)4 BlockCipher (org.bouncycastle.crypto.BlockCipher)4 InvalidCipherTextIOException (org.bouncycastle.crypto.io.InvalidCipherTextIOException)4 ParametersWithIV (org.bouncycastle.crypto.params.ParametersWithIV)4 Test (org.junit.Test)4 FileInputStream (java.io.FileInputStream)3 FileNotFoundException (java.io.FileNotFoundException)3 InputStream (java.io.InputStream)3 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)3