use of javax.crypto.spec.GCMParameterSpec in project wigle-wifi-wardriving by wiglenet.
the class TokenAccess method getApiTokenVersion2.
private static String getApiTokenVersion2(SharedPreferences prefs) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchPaddingException, InvalidKeyException, UnrecoverableEntryException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
try {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
// GCMParameterSpec not in < 19 - prevent compiler warnings
MainActivity.warn("[TOKEN] getApiTokenVersion2 sdk not K+: " + Build.VERSION.SDK_INT);
return null;
} else {
final KeyStore keyStore = getKeyStore();
final SecretKey key = (SecretKey) keyStore.getKey(KEYSTORE_WIGLE_CREDS_KEY_V2, null);
final Cipher decrypt = Cipher.getInstance(AES_CIPHER);
final byte[] cypherToken = Base64.decode(prefs.getString(ListFragment.PREF_TOKEN, ""), Base64.DEFAULT);
final byte[] iv = Base64.decode(prefs.getString(ListFragment.PREF_TOKEN_IV, ""), Base64.DEFAULT);
final int tagLength = prefs.getInt(ListFragment.PREF_TOKEN_TAG_LENGTH, 128);
decrypt.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(tagLength, iv));
final byte[] done = decrypt.doFinal(cypherToken);
final String token = new String(done, UTF8);
MainActivity.info("[TOKEN] aes decrypted token length: " + token.length());
return token;
}
} catch (Exception ex) {
MainActivity.error("Failed to decrypt token with AES-GCM (v2 cipher): ", ex);
return null;
}
}
use of javax.crypto.spec.GCMParameterSpec in project scout.rt by eclipse.
the class SunSecurityProvider method createEncryptionKey.
@Override
public EncryptionKey createEncryptionKey(char[] password, byte[] salt, int keyLen) {
Assertions.assertGreater(Assertions.assertNotNull(password, "password must not be null.").length, 0, "empty password is not allowed.");
Assertions.assertGreater(Assertions.assertNotNull(salt, "salt must be provided.").length, 0, "empty salt is not allowed.");
Assertions.assertTrue(keyLen == 128 || keyLen == 192 || keyLen == 256, "key length must be 128, 192 or 256.");
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(getSecretKeyAlgorithm(), getCipherAlgorithmProvider());
KeySpec spec = new PBEKeySpec(password, salt, getKeyDerivationIterationCount(), keyLen + (GCM_INITIALIZATION_VECTOR_LEN * 8));
SecretKey tmpSecret = factory.generateSecret(spec);
// derive Key and Initialization Vector
byte[] encoded = tmpSecret.getEncoded();
byte[] iv = new byte[GCM_INITIALIZATION_VECTOR_LEN];
byte[] key = new byte[keyLen / 8];
System.arraycopy(encoded, 0, key, 0, key.length);
System.arraycopy(encoded, key.length, iv, 0, GCM_INITIALIZATION_VECTOR_LEN);
SecretKey secretKey = new SecretKeySpec(key, getCipherAlgorithm());
GCMParameterSpec parameters = new GCMParameterSpec(GCM_AUTH_TAG_BIT_LEN, iv);
return new EncryptionKey(secretKey, parameters);
} catch (NoSuchAlgorithmException e) {
throw new ProcessingException("Unable to create secret. Algorithm could not be found. Make sure to use JRE 1.8 or newer.", e);
} catch (InvalidKeySpecException | NoSuchProviderException e) {
throw new ProcessingException("Unable to create secret.", e);
}
}
use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.
the class AesGcmTest method testWrappedAroundCounter.
/**
* Test AES-GCM wrapped around counter bug which leaks plaintext and authentication key. Let's
* consider 12-byte IV, counter = IV || 0^31 || 1. For each encryption block, the last 4 bytes of
* the counter is increased by 1. After 2^32 blocks, the counter will be wrapped around causing
* counter collision and hence, leaking plaintext and authentication key as explained below. The
* library must make a check to make sure that the plaintext's length never exceeds 2^32 - 2
* blocks. Note that this is different from usual IV collisions because it happens even if users
* use different IVs. <br>
* We have: <br>
* J0 = IV || 0^31 || 1 <br>
* Plaintext: P[0], P[1], P[2], .... <br>
* Ciphertext: <br>
* C[0] = Enc(K, (J0 + 1) % 2^32) XOR P[0] <br>
* C[1] = Enc(K, (J0 + 2) % 2^32) XOR P[1] <br>
* C[2] = Enc(K, (J0 + 3) % 2^32) XOR P[2] <br>
* ... <br>
* C[2^32 - 1] = Enc(K, J0) XOR P[2^32 - 1] <br>
* C[2^32] = Enc(K, (J0 + 1)% 2^32) XOR P[2^32] <br>
* It means that after 2^32 blocks, the counter is wrapped around causing counter collisions. In
* counter mode, once the counter is collided then it's reasonable to assume that the plaintext is
* leaked. As the ciphertext is already known to attacker, Enc(K, J0) is leaked. <br>
* Now, as the authentication tag T is computed as GHASH(H, {}, C) XOR E(K, J0), the attacker can
* learn GHASH(H, {}, C}. It essentially means that the attacker finds a polynomial where H is the
* root (see Joux attack http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/Joux_comments.pdf).
* Solving polynomial equation in GF(2^128) is enough to extract the authentication key.
*
* <p>BouncyCastle used to have this bug (CVE-2015-6644).
*
* <p>OpenJDK8 used to have this bug (http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/0c3ed12cdaf5)
*
* <p>The test is slow as we have to encrypt 2^32 blocks.
*/
@ExcludedTest(providers = { ProviderType.CONSCRYPT, ProviderType.BOUNCY_CASTLE, ProviderType.SPONGY_CASTLE }, comment = "Conscrypt doesn't support streaming, would crash. BouncyCastle needs > 1h.")
@SlowTest(providers = { ProviderType.BOUNCY_CASTLE, ProviderType.CONSCRYPT, ProviderType.OPENJDK, ProviderType.SPONGY_CASTLE })
@Test
public void testWrappedAroundCounter() throws Exception {
try {
byte[] iv = new byte[12];
byte[] input = new byte[16];
byte[] key = new byte[16];
(new SecureRandom()).nextBytes(key);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(16 * 8, iv));
byte[] output = cipher.update(input);
for (long i = 0; i < 4294967296L + 2; i++) {
byte[] output1 = cipher.update(input);
assertFalse("GCM Wrapped Around Counter" + i, Arrays.equals(output, output1));
}
fail("Expected Exception");
} catch (Exception expected) {
System.out.println("testWrappedAroundcounter:" + expected.toString());
}
}
use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.
the class AesGcmTest method testLargeArrayAlias.
/**
* Encryption and decryption with large arrays should be copy-safe.
*/
@NoPresubmitTest(providers = { ProviderType.BOUNCY_CASTLE }, bugs = { "b/64378943" })
@Test
public void testLargeArrayAlias() throws Exception {
byte[] ptVector = new byte[8192];
// this offset is relative to the start of the input, not the start of the buffer.
for (int outputOffset = -32; outputOffset <= 32; outputOffset++) {
// try with doFinal directly as well as with update followed by doFinal
for (int useUpdate = 0; useUpdate <= 1; useUpdate++) {
SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
GCMParameterSpec parameters = new GCMParameterSpec(128, new byte[12]);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, parameters);
// these offsets are relative to the start of the buffer
int inputOffsetInBuffer = 32;
int outputOffsetInBuffer = inputOffsetInBuffer + outputOffset;
int sliceLength = cipher.getOutputSize(ptVector.length);
byte[] inBuf = new byte[sliceLength + Math.max(inputOffsetInBuffer, outputOffsetInBuffer)];
byte[] outBuf = inBuf;
System.arraycopy(ptVector, 0, inBuf, inputOffsetInBuffer, ptVector.length);
try {
int ctLength = 0;
if (useUpdate > 0) {
ctLength += cipher.update(inBuf, inputOffsetInBuffer, ptVector.length, outBuf, outputOffsetInBuffer);
ctLength += cipher.doFinal(inBuf, 0, 0, outBuf, outputOffsetInBuffer + ctLength);
} else {
ctLength += cipher.doFinal(inBuf, inputOffsetInBuffer, ptVector.length, outBuf, outputOffsetInBuffer);
}
System.arraycopy(outBuf, outputOffsetInBuffer, inBuf, inputOffsetInBuffer, ctLength);
cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, parameters);
int resultPtLength = 0;
if (useUpdate > 0) {
resultPtLength += cipher.update(inBuf, inputOffsetInBuffer, ctLength, outBuf, outputOffsetInBuffer);
resultPtLength += cipher.doFinal(inBuf, 0, 0, outBuf, outputOffsetInBuffer + resultPtLength);
} else {
resultPtLength += cipher.doFinal(inBuf, inputOffsetInBuffer, ctLength, outBuf, outputOffsetInBuffer);
}
assertEquals(resultPtLength, ptVector.length);
assertArrayEquals(ptVector, Arrays.copyOfRange(outBuf, outputOffsetInBuffer, outputOffsetInBuffer + resultPtLength));
} catch (Throwable t) {
throw new AssertionError("testLargeByteBufferAlias failed with outputOffset=" + outputOffset, t);
}
}
}
}
use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.
the class AesGcmTest method testDecryptWithEmptyIv.
@NoPresubmitTest(providers = { ProviderType.OPENJDK }, bugs = { "b/35746778" })
@Test
public void testDecryptWithEmptyIv() throws Exception {
byte[] emptyIv = new byte[0];
byte[] key = TestUtil.hexToBytes("56aae7bd5cbefc71d31c4338e6ddd6c5");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
try {
cipher.init(Cipher.DECRYPT_MODE, keySpec, new GCMParameterSpec(16 * 8, emptyIv));
String ciphertext = "2b65876c00d77facf8f3d0e5be792b129bab10b25bcb739b92d6e2eab241245ff449";
String tag = "c2b2d7086e7fa84ca795a881b540";
byte[] pt1 = cipher.update(TestUtil.hexToBytes(ciphertext));
byte[] pt2 = cipher.doFinal(TestUtil.hexToBytes(tag));
// We shouldn't get here. If a provider releases unverified plaintext additionally to
// accepting empty IVs then chosen ciphertext attacks might be possible.
System.out.println("testDecryptWithEmptyIv:");
System.out.println("pt1:" + TestUtil.bytesToHex(pt1));
System.out.println("pt2:" + TestUtil.bytesToHex(pt2));
fail("AES-GCM must not accept an IV of size 0.");
} catch (GeneralSecurityException expected) {
System.out.println("testDecryptWithEmptyIv:" + expected.toString());
}
}
Aggregations