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());
}
}
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");
}
}
use of org.bouncycastle.crypto.modes.GCMBlockCipher in project XobotOS by xamarin.
the class JCEBlockCipher method engineSetMode.
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
modeName = Strings.toUpperCase(mode);
if (modeName.equals("ECB")) {
ivLength = 0;
cipher = new BufferedGenericBlockCipher(baseEngine);
} else if (modeName.equals("CBC")) {
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new CBCBlockCipher(baseEngine));
} else if (modeName.startsWith("OFB")) {
ivLength = baseEngine.getBlockSize();
if (modeName.length() != 3) {
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(new OFBBlockCipher(baseEngine, wordSize));
} else {
cipher = new BufferedGenericBlockCipher(new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
} else if (modeName.startsWith("CFB")) {
ivLength = baseEngine.getBlockSize();
if (modeName.length() != 3) {
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(new CFBBlockCipher(baseEngine, wordSize));
} else {
cipher = new BufferedGenericBlockCipher(new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
} else // END android-removed
if (modeName.startsWith("SIC")) {
ivLength = baseEngine.getBlockSize();
if (ivLength < 16) {
throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
}
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(new SICBlockCipher(baseEngine)));
} else if (modeName.startsWith("CTR")) {
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(new SICBlockCipher(baseEngine)));
} else if (modeName.startsWith("GOFB")) {
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(new GOFBBlockCipher(baseEngine)));
} else if (modeName.startsWith("CTS")) {
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
} else if (modeName.startsWith("CCM")) {
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
} else // END android-removed
if (modeName.startsWith("GCM")) {
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
} else {
throw new NoSuchAlgorithmException("can't support mode " + mode);
}
}
use of org.bouncycastle.crypto.modes.GCMBlockCipher in project oxAuth by GluuFederation.
the class JweEncrypterImpl method generateCipherTextAndIntegrityValue.
@Override
public Pair<String, String> generateCipherTextAndIntegrityValue(byte[] contentMasterKey, byte[] initializationVector, byte[] additionalAuthenticatedData, byte[] plainText) throws InvalidJweException {
if (getBlockEncryptionAlgorithm() == null) {
throw new InvalidJweException("The block encryption algorithm is null");
}
if (contentMasterKey == null) {
throw new InvalidJweException("The content master key (CMK) is null");
}
if (initializationVector == null) {
throw new InvalidJweException("The initialization vector is null");
}
if (additionalAuthenticatedData == null) {
throw new InvalidJweException("The additional authentication data is null");
}
if (plainText == null) {
throw new InvalidJweException("The plain text to encrypt is null");
}
try {
if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128GCM || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256GCM) {
SecretKey secretKey = new SecretKeySpec(contentMasterKey, "AES");
KeyParameter key = new KeyParameter(contentMasterKey);
final int MAC_SIZE_BITS = 128;
AEADParameters aeadParameters = new AEADParameters(key, MAC_SIZE_BITS, initializationVector, additionalAuthenticatedData);
final int macSize = aeadParameters.getMacSize() / 8;
BlockCipher blockCipher = new AESEngine();
CipherParameters params = new KeyParameter(secretKey.getEncoded());
blockCipher.init(true, params);
GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher);
aGCMBlockCipher.init(true, aeadParameters);
int len = aGCMBlockCipher.getOutputSize(plainText.length);
byte[] out = new byte[len];
int outOff = aGCMBlockCipher.processBytes(plainText, 0, plainText.length, out, 0);
outOff += aGCMBlockCipher.doFinal(out, outOff);
byte[] cipherText = new byte[outOff - macSize];
System.arraycopy(out, 0, cipherText, 0, cipherText.length);
byte[] authenticationTag = new byte[macSize];
System.arraycopy(out, outOff - macSize, authenticationTag, 0, authenticationTag.length);
String encodedCipherText = Base64Util.base64urlencode(cipherText);
String encodedAuthenticationTag = Base64Util.base64urlencode(authenticationTag);
return new Pair<String, String>(encodedCipherText, encodedAuthenticationTag);
} else if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128CBC_PLUS_HS256 || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256CBC_PLUS_HS512) {
byte[] cek = KeyDerivationFunction.generateCek(contentMasterKey, getBlockEncryptionAlgorithm());
IvParameterSpec parameters = new IvParameterSpec(initializationVector);
Cipher cipher = Cipher.getInstance(getBlockEncryptionAlgorithm().getAlgorithm(), "BC");
//Cipher cipher = Cipher.getInstance(getBlockEncryptionAlgorithm().getAlgorithm());
SecretKeySpec secretKeySpec = new SecretKeySpec(cek, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, parameters);
byte[] cipherText = cipher.doFinal(plainText);
String encodedCipherText = Base64Util.base64urlencode(cipherText);
String securedInputValue = new String(additionalAuthenticatedData, Charset.forName(Util.UTF8_STRING_ENCODING)) + "." + encodedCipherText;
byte[] cik = KeyDerivationFunction.generateCik(contentMasterKey, getBlockEncryptionAlgorithm());
SecretKey secretKey = new SecretKeySpec(cik, getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
Mac mac = Mac.getInstance(getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
mac.init(secretKey);
byte[] integrityValue = mac.doFinal(securedInputValue.getBytes(Util.UTF8_STRING_ENCODING));
String encodedIntegrityValue = Base64Util.base64urlencode(integrityValue);
return new Pair<String, String>(encodedCipherText, encodedIntegrityValue);
} else {
throw new InvalidJweException("The block encryption algorithm is not supported");
}
} catch (InvalidCipherTextException e) {
throw new InvalidJweException(e);
} catch (NoSuchAlgorithmException e) {
throw new InvalidJweException(e);
} catch (UnsupportedEncodingException e) {
throw new InvalidJweException(e);
} catch (NoSuchProviderException e) {
throw new InvalidJweException(e);
} catch (IllegalBlockSizeException e) {
throw new InvalidJweException(e);
} catch (InvalidKeyException e) {
throw new InvalidJweException(e);
} catch (BadPaddingException e) {
throw new InvalidJweException(e);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidJweException(e);
} catch (NoSuchPaddingException e) {
throw new InvalidJweException(e);
} catch (InvalidParameterException e) {
throw new InvalidJweException(e);
}
}
Aggregations