Search in sources :

Example 6 with AESEngine

use of org.bouncycastle.crypto.engines.AESEngine in project inbot-utils by Inbot.

the class AESUtils method decryptBouncyCastle.

private static String decryptBouncyCastle(SecretKey secret, String input) {
    try {
        // Convert url-safe base64 to normal base64, remove carriage returns
        input = input.replaceAll("-", "+").replaceAll("_", "/").replaceAll("\r", "").replaceAll("\n", "");
        String[] splitInput = SPLIT_PATTERN.split(input);
        byte[] iv = hexStringToByteArray(splitInput[0]);
        byte[] encrypted = Base64.decodeBase64(splitInput[1]);
        // get raw key from password and salt
        byte[] key = secret.getEncoded();
        // setup cipher parameters with key and IV
        KeyParameter keyParam = new KeyParameter(key);
        CipherParameters params = new ParametersWithIV(keyParam, iv);
        // setup AES cipher in CBC mode with PKCS7 padding
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding());
        cipher.reset();
        cipher.init(false, params);
        // create a temporary buffer to decode into (it'll include padding)
        byte[] buf = new byte[cipher.getOutputSize(encrypted.length)];
        int len = cipher.processBytes(encrypted, 0, encrypted.length, buf, 0);
        len += cipher.doFinal(buf, len);
        // lose the padding
        byte[] out = new byte[len];
        System.arraycopy(buf, 0, out, 0, len);
        // lose the salt
        String plaintext = new String(out, StandardCharsets.UTF_8);
        String md5Hash = plaintext.substring(0, 22);
        String plainTextWithoutHash = plaintext.substring(22);
        if (md5Hash.equals(HashUtils.md5(plainTextWithoutHash))) {
            return plainTextWithoutHash;
        } else {
            // it's possible to decrypt to garbage with the wrong key; the md5 check helps detecting that
            throw new IllegalArgumentException("wrong aes key - incorrect content hash");
        }
    } catch (DataLengthException e) {
        throw new IllegalStateException("buffer not big enough", e);
    } catch (InvalidCipherTextException e) {
        throw new IllegalArgumentException("wrong password");
    }
}
Also used : PaddedBufferedBlockCipher(org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher) AESEngine(org.bouncycastle.crypto.engines.AESEngine) InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) CipherParameters(org.bouncycastle.crypto.CipherParameters) ParametersWithIV(org.bouncycastle.crypto.params.ParametersWithIV) PKCS7Padding(org.bouncycastle.crypto.paddings.PKCS7Padding) BufferedBlockCipher(org.bouncycastle.crypto.BufferedBlockCipher) PaddedBufferedBlockCipher(org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher) DataLengthException(org.bouncycastle.crypto.DataLengthException) CBCBlockCipher(org.bouncycastle.crypto.modes.CBCBlockCipher)

Example 7 with AESEngine

use of org.bouncycastle.crypto.engines.AESEngine in project elastic-core-maven by OrdinaryDude.

the class Crypto method aesDecrypt.

public static byte[] aesDecrypt(byte[] ivCiphertext, byte[] key) {
    try {
        if (ivCiphertext.length < 16 || ivCiphertext.length % 16 != 0) {
            throw new InvalidCipherTextException("invalid ivCiphertext length");
        }
        byte[] iv = Arrays.copyOfRange(ivCiphertext, 0, 16);
        byte[] ciphertext = Arrays.copyOfRange(ivCiphertext, 16, ivCiphertext.length);
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
        aes.init(false, ivAndKey);
        byte[] output = new byte[aes.getOutputSize(ciphertext.length)];
        int plaintextLength = aes.processBytes(ciphertext, 0, ciphertext.length, output, 0);
        plaintextLength += aes.doFinal(output, plaintextLength);
        byte[] result = new byte[plaintextLength];
        System.arraycopy(output, 0, result, 0, result.length);
        return result;
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}
Also used : CipherParameters(org.bouncycastle.crypto.CipherParameters) ParametersWithIV(org.bouncycastle.crypto.params.ParametersWithIV) InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) PaddedBufferedBlockCipher(org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher) AESEngine(org.bouncycastle.crypto.engines.AESEngine) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) CBCBlockCipher(org.bouncycastle.crypto.modes.CBCBlockCipher)

Example 8 with AESEngine

use of org.bouncycastle.crypto.engines.AESEngine in project syncany by syncany.

the class AesGcmCipherSpec method newCipherOutputStream.

@Override
public OutputStream newCipherOutputStream(OutputStream underlyingOutputStream, byte[] secretKey, byte[] iv) throws CipherException {
    AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    cipher.init(true, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv));
    return new org.bouncycastle.crypto.io.CipherOutputStream(underlyingOutputStream, cipher);
}
Also used : AESEngine(org.bouncycastle.crypto.engines.AESEngine) AEADParameters(org.bouncycastle.crypto.params.AEADParameters) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher) AEADBlockCipher(org.bouncycastle.crypto.modes.AEADBlockCipher)

Example 9 with AESEngine

use of org.bouncycastle.crypto.engines.AESEngine 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 10 with AESEngine

use of org.bouncycastle.crypto.engines.AESEngine 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

AESEngine (org.bouncycastle.crypto.engines.AESEngine)17 KeyParameter (org.bouncycastle.crypto.params.KeyParameter)17 GCMBlockCipher (org.bouncycastle.crypto.modes.GCMBlockCipher)12 AEADParameters (org.bouncycastle.crypto.params.AEADParameters)10 CipherParameters (org.bouncycastle.crypto.CipherParameters)8 InvalidCipherTextException (org.bouncycastle.crypto.InvalidCipherTextException)8 AEADBlockCipher (org.bouncycastle.crypto.modes.AEADBlockCipher)8 ParametersWithIV (org.bouncycastle.crypto.params.ParametersWithIV)7 CBCBlockCipher (org.bouncycastle.crypto.modes.CBCBlockCipher)5 PaddedBufferedBlockCipher (org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 IvParameterSpec (javax.crypto.spec.IvParameterSpec)4 SecretKeySpec (javax.crypto.spec.SecretKeySpec)4 InvalidCipherTextIOException (org.bouncycastle.crypto.io.InvalidCipherTextIOException)4 Test (org.junit.Test)4 BufferedBlockCipher (org.bouncycastle.crypto.BufferedBlockCipher)3 PKCS7Padding (org.bouncycastle.crypto.paddings.PKCS7Padding)3 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)2