private void testTampering(boolean aeadAvailable) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC"); final SecretKeySpec key = new SecretKeySpec(new byte[eax.getBlockSize()], eax.getAlgorithm()); final IvParameterSpec iv = new IvParameterSpec(new byte[eax.getBlockSize()]); eax.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = eax.doFinal(new byte[100]); ciphertext[0] = (byte) (ciphertext[0] + 1); // Tamper try { eax.init(Cipher.DECRYPT_MODE, key, iv); eax.doFinal(ciphertext); fail("Tampered ciphertext should be invalid"); } catch (BadPaddingException e) { if (aeadAvailable) { if (!e.getClass().getName().equals("javax.crypto.AEADBadTagException")) { fail("Tampered AEAD ciphertext should fail with AEADBadTagException when available."); } } } }
void showCipher(Cipher c, String kind) { System.out.println(kind + " cipher provider: " + cipher.getProvider()); System.out.println(kind + " cipher algorithm: " + cipher.getAlgorithm()); }
EncryptedFormInformation( String formId, String formVersion, FormController.InstanceMetadata instanceMetadata, PublicKey rsaPublicKey, Base64Wrapper wrapper) { this.formId = formId; this.formVersion = formVersion; this.instanceMetadata = instanceMetadata; this.rsaPublicKey = rsaPublicKey; this.wrapper = wrapper; // generate the symmetric key from random bits... SecureRandom r = new SecureRandom(); byte[] key = new byte[SYMMETRIC_KEY_LENGTH / 8]; r.nextBytes(key); SecretKeySpec sk = new SecretKeySpec(key, SYMMETRIC_ALGORITHM); symmetricKey = sk; // construct the fixed portion of the iv -- the ivSeedArray // this is the md5 hash of the instanceID and the symmetric key try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(instanceMetadata.instanceId.getBytes(UTF_8)); md.update(key); byte[] messageDigest = md.digest(); ivSeedArray = new byte[IV_BYTE_LENGTH]; for (int i = 0; i < IV_BYTE_LENGTH; ++i) { ivSeedArray[i] = messageDigest[(i % messageDigest.length)]; } } catch (NoSuchAlgorithmException e) { Log.e(t, e.toString()); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } catch (UnsupportedEncodingException e) { Log.e(t, e.toString()); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } // construct the base64-encoded RSA-encrypted symmetric key try { Cipher pkCipher; pkCipher = Cipher.getInstance(ASYMMETRIC_ALGORITHM); // write AES key pkCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); byte[] pkEncryptedKey = pkCipher.doFinal(key); String alg = pkCipher.getAlgorithm(); Log.i(t, "AlgorithmUsed: " + alg); base64RsaEncryptedSymmetricKey = wrapper.encodeToString(pkEncryptedKey); } catch (NoSuchAlgorithmException e) { Log.e(t, "Unable to encrypt the symmetric key"); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } catch (NoSuchPaddingException e) { Log.e(t, "Unable to encrypt the symmetric key"); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } catch (InvalidKeyException e) { Log.e(t, "Unable to encrypt the symmetric key"); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } catch (IllegalBlockSizeException e) { Log.e(t, "Unable to encrypt the symmetric key"); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } catch (BadPaddingException e) { Log.e(t, "Unable to encrypt the symmetric key"); e.printStackTrace(); throw new IllegalArgumentException(e.getMessage()); } // start building elementSignatureSource... appendElementSignatureSource(formId); if (formVersion != null) { appendElementSignatureSource(formVersion.toString()); } appendElementSignatureSource(base64RsaEncryptedSymmetricKey); appendElementSignatureSource(instanceMetadata.instanceId); }