private static void newGCMParameterSpecPass( int tLen, byte[] src, int offset, int len) { try { GCMParameterSpec gcmps = new GCMParameterSpec(tLen, src, offset, len); if (gcmps.getTLen() != tLen) { throw new Exception("tLen's not equal"); } if (!Arrays.equals(gcmps.getIV(), Arrays.copyOfRange(src, offset, offset + len))) { System.out.println(offset + " " + len); System.out.println(Arrays.copyOfRange(src, offset, len)[0]); throw new Exception("IV's not equal"); } } catch (Exception e) { e.printStackTrace(); failed++; } }
public String decrypt(final String alias, final byte[] encryptedData, Context appContext) throws UnrecoverableEntryException, NoSuchAlgorithmException, KeyStoreException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { final Cipher cipher = Cipher.getInstance(TRANSFORMATION); String IV = PreferenceHelper.getPrefernceHelperInstace().getString(appContext, "IV", ""); if (null != IV && !IV.isEmpty()) { byte[] encryptionIv = Base64.decode(IV, Base64.DEFAULT); Log.e("Decrypter", "IV : " + IV + " IV size " + encryptionIv.length); final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv); cipher.init(Cipher.DECRYPT_MODE, getSecretKey(alias), spec); return new String(cipher.doFinal(encryptedData), "UTF-8"); } else { return "{}"; } }
Boolean isAvailable() { // We won't know whether a cipher for a particular key size is // available until the cipher is successfully initialized. // // We do not initialize AEAD cipher in the constructor. Need to // initialize the cipher to ensure that the AEAD mode for a // particular key size is supported. if (cipherType == AEAD_CIPHER) { try { Authenticator authenticator = new Authenticator(protocolVersion); byte[] nonce = authenticator.sequenceNumber(); byte[] iv = Arrays.copyOf(fixedIv, fixedIv.length + nonce.length); System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length); GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); cipher.init(mode, key, spec, random); } catch (Exception e) { return Boolean.FALSE; } } // Otherwise, we have initialized the cipher in the constructor. return Boolean.TRUE; }
private byte[] getCipherTextBySpec(GCMParameterSpec spec) throws Exception { // init a cipher Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, spec); cipher.updateAAD(AAD); byte[] cipherText = cipher.doFinal(data); // check IVs if (!Arrays.equals(cipher.getIV(), spec.getIV())) { System.out.println("IV in parameters is incorrect"); return null; } if (spec.getTLen() != (cipherText.length - data.length) * 8) { System.out.println("Tag length is incorrect"); return null; } return cipherText; }
private void doTestWithSeparateArrays(int offset, AlgorithmParameters params) throws Exception { // prepare buffers to test Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); int outputLength = c.getOutputSize(textLength); int outputBufSize = outputLength + offset * 2; byte[] inputText = Helper.generateBytes(outputBufSize); byte[] AAD = Helper.generateBytes(AADLength); // do the test runGCMWithSeparateArray(Cipher.ENCRYPT_MODE, AAD, inputText, offset * 2, textLength, offset, params); int tagLength = c.getParameters() .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; runGCMWithSeparateArray(Cipher.DECRYPT_MODE, AAD, inputText, offset, textLength + tagLength, offset, params); }
/** * Run the test in case when AAD and text are placed in the same byte * array. */ private void doTestWithSameArrays(int offset, AlgorithmParameters params) throws Exception { // prepare buffers to test Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); int outputLength = c.getOutputSize(textLength); int outputBufSize = AADLength + outputLength + offset * 2; byte[] AAD_and_text = Helper.generateBytes(outputBufSize); // do the test runGCMWithSameArray(Cipher.ENCRYPT_MODE, AAD_and_text, AADLength + offset, textLength, params); int tagLength = c.getParameters() .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; runGCMWithSameArray(Cipher.DECRYPT_MODE, AAD_and_text, AADLength + offset, textLength + tagLength, params); }
private void doTestWithSameBuffer(int offset, AlgorithmParameters params) throws Exception { // calculate output length Cipher c = createCipher(Cipher.ENCRYPT_MODE, params); int outputLength = c.getOutputSize(textLength); // prepare byte buffer contained AAD and plain text int bufSize = AADLength + offset + outputLength; byte[] AAD_and_Text = Helper.generateBytes(bufSize); ByteBuffer AAD_and_Text_Buf = ByteBuffer.allocate(bufSize); AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length); // do test runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset, textLength, params); int tagLength = c.getParameters() .getParameterSpec(GCMParameterSpec.class).getTLen() / 8; AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength); runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset, textLength + tagLength, params); }
@Override protected synchronized AlgorithmParameters engineGetParameters() { AlgorithmParameters params = null; try { if (iv != null) { GCMParameterSpec gcmSpec = new GCMParameterSpec(tagLen, iv.clone()); params = AlgorithmParameters.getInstance("GCM"); params.init(gcmSpec); } } catch (GeneralSecurityException e) { // NoSuchAlgorithmException, NoSuchProviderException // InvalidParameterSpecException throw new UcryptoException("Could not encode parameters", e); } return params; }
public static String encryptString(String password, String value) { String salt = KeyGenerators.string().generateKey(); SecretKeySpec skeySpec = makeKeySpec(password, salt); byte[] iv = KeyGenerators.secureRandom(16).generateKey(); String ivString = Hex.encodeHexString(iv); try { Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new GCMParameterSpec(128, iv)); /* Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(iv)); */ byte[] encrypted = cipher.doFinal(value.getBytes(Charset.forName("UTF-8"))); String s = StringUtils.strip(new Base32().encodeAsString(encrypted), "=").toLowerCase(); // Strip line breaks s = salt + ivString + s.replaceAll("(\\n|\\r)", ""); return s; } catch (Exception e) { throw new RuntimeException(e); } }
private EncryptionResult encryptTLS12(EncryptionRequest request) { try { byte[] nonce = ArrayConverter.longToBytes(context.getWriteSequenceNumber(), RecordByteLength.SEQUENCE_NUMBER); byte[] iv = ArrayConverter.concatenate( getKeySet().getWriteIv(context.getConnection().getLocalConnectionEndType()), nonce); encryptIV = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv); LOGGER.debug("Encrypting GCM with the following IV: {}", ArrayConverter.bytesToHexString(encryptIV.getIV())); encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey, encryptIV); LOGGER.debug("Encrypting GCM with the following AAD: {}", ArrayConverter.bytesToHexString(additionalAuthenticatedData)); encryptCipher.updateAAD(additionalAuthenticatedData); byte[] ciphertext = encryptCipher.doFinal(request.getPlainText()); return new EncryptionResult(encryptIV.getIV(), ArrayConverter.concatenate(nonce, ciphertext), false); } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | InvalidAlgorithmParameterException ex) { throw new CryptoException(ex); } }
private byte[] decryptTLS12(byte[] data) { try { byte[] nonce = Arrays.copyOf(data, SEQUENCE_NUMBER_LENGTH); data = Arrays.copyOfRange(data, SEQUENCE_NUMBER_LENGTH, data.length); byte[] iv = ArrayConverter.concatenate( getKeySet().getReadIv(context.getConnection().getLocalConnectionEndType()), nonce); decryptIV = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv); LOGGER.debug("Decrypting GCM with the following IV: {}", ArrayConverter.bytesToHexString(decryptIV.getIV())); decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey, decryptIV); LOGGER.debug("Decrypting GCM with the following AAD: {}", ArrayConverter.bytesToHexString(additionalAuthenticatedData)); decryptCipher.updateAAD(additionalAuthenticatedData); LOGGER.debug("Decrypting the following GCM ciphertext: {}", ArrayConverter.bytesToHexString(data)); return decryptCipher.doFinal(data); } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | InvalidAlgorithmParameterException ex) { throw new CryptoException(ex); } }
public GcmTestVector( String message, String keyMaterial, String nonce, String aad, String ciphertext, String tag) { this.ptHex = message; this.pt = TestUtil.hexToBytes(message); this.aad = TestUtil.hexToBytes(aad); this.ct = TestUtil.hexToBytes(ciphertext + tag); this.ctHex = ciphertext + tag; this.tagLengthInBits = 4 * tag.length(); this.nonceLengthInBits = 4 * nonce.length(); this.parameters = new GCMParameterSpec(tagLengthInBits, TestUtil.hexToBytes(nonce)); this.key = new SecretKeySpec(TestUtil.hexToBytes(keyMaterial), "AES"); }
byte[] decrypt(byte[] message) throws Exception { if(message==null || message.length < GCM_NONCE_LENGTH + GCM_TAG_LENGTH) { // needs room for message + IV + authentication tag if(optionalDecrypt) { CTinfo.debugPrint("Warning: Decrypt failed, returning raw data"); return message; // quietly fail } else throw new IllegalArgumentException(); } Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec params = new GCMParameterSpec(8*GCM_TAG_LENGTH, message, 0, GCM_NONCE_LENGTH); cipher.init(Cipher.DECRYPT_MODE, secretKey, params); try { return cipher.doFinal(message, GCM_NONCE_LENGTH, message.length - GCM_NONCE_LENGTH); // skip IV at start } catch(Exception e) { if(optionalDecrypt) { CTinfo.debugPrint("Warning: decrypt failed, returning raw data"); return message; } else throw e; } }
@NonNull private String decryptCurrentKeystoreVersion(String encryptedData) throws KeyStoreException { try { final Cipher cipher = Cipher.getInstance(TRANSFORMATION); final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec); final byte[] encryptedBytes = Base64.decode(encryptedData, Base64.DEFAULT); final byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, UTF_8); } catch (UnrecoverableEntryException | UnsupportedEncodingException | IllegalBlockSizeException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException | java.security.KeyStoreException | BadPaddingException | NoSuchAlgorithmException e) { throw new KeyStoreException(new Throwable(e.getMessage())); } }
@Override public byte[] encrypt(byte[] rawEncryptionKey, byte[] rawData, @Nullable byte[] associatedData) throws AuthenticatedEncryptionException { if (rawEncryptionKey.length < 16) { throw new IllegalArgumentException("key length must be longer than 16 byte"); } try { byte[] iv = new byte[IV_LENGTH_BYTE]; secureRandom.nextBytes(iv); final Cipher cipher = getCipher(); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(rawEncryptionKey, "AES"), new GCMParameterSpec(TAG_LENGTH_BIT, iv)); if (associatedData != null) { cipher.updateAAD(associatedData); } byte[] encrypted = cipher.doFinal(rawData); ByteBuffer byteBuffer = ByteBuffer.allocate(1 + iv.length + encrypted.length); byteBuffer.put((byte) iv.length); byteBuffer.put(iv); byteBuffer.put(encrypted); return byteBuffer.array(); } catch (Exception e) { throw new AuthenticatedEncryptionException("could not encrypt", e); } }
@Override public byte[] decrypt(byte[] rawEncryptionKey, byte[] encryptedData, @Nullable byte[] associatedData) throws AuthenticatedEncryptionException { try { ByteBuffer byteBuffer = ByteBuffer.wrap(encryptedData); int ivLength = byteBuffer.get(); byte[] iv = new byte[ivLength]; byteBuffer.get(iv); byte[] encrypted = new byte[byteBuffer.remaining()]; byteBuffer.get(encrypted); final Cipher cipher = getCipher(); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(rawEncryptionKey, "AES"), new GCMParameterSpec(TAG_LENGTH_BIT, iv)); if (associatedData != null) { cipher.updateAAD(associatedData); } byte[] decrypted = cipher.doFinal(encrypted); Bytes.wrap(iv).mutable().secureWipe(); Bytes.wrap(rawEncryptionKey).mutable().secureWipe(); Bytes.wrap(encrypted).mutable().secureWipe(); return decrypted; } catch (Exception e) { throw new AuthenticatedEncryptionException("could not decrypt", e); } }
private PairSetupPin3Response doPairSetupPin3(Socket socket, final byte[] sessionKeyHashK) throws Exception { MessageDigest sha512Digest = MessageDigest.getInstance("SHA-512"); sha512Digest.update("Pair-Setup-AES-Key".getBytes(StandardCharsets.UTF_8)); sha512Digest.update(sessionKeyHashK); byte[] aesKey = Arrays.copyOfRange(sha512Digest.digest(), 0, 16); sha512Digest.update("Pair-Setup-AES-IV".getBytes(StandardCharsets.UTF_8)); sha512Digest.update(sessionKeyHashK); byte[] aesIV = Arrays.copyOfRange(sha512Digest.digest(), 0, 16); int lengthB; int lengthA = lengthB = aesIV.length - 1; for (; lengthB >= 0 && 256 == ++aesIV[lengthA]; lengthA = lengthB += -1) ; Cipher aesGcm128Encrypt = Cipher.getInstance("AES/GCM/NoPadding"); SecretKeySpec secretKey = new SecretKeySpec(aesKey, "AES"); aesGcm128Encrypt.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, aesIV)); final byte[] aesGcm128ClientLTPK = aesGcm128Encrypt.doFinal(authKey.getAbyte()); byte[] pairSetupPinRequestData = AuthUtils.createPList(new HashMap<String, byte[]>() {{ put("epk", Arrays.copyOfRange(aesGcm128ClientLTPK, 0, aesGcm128ClientLTPK.length - 16)); put("authTag", Arrays.copyOfRange(aesGcm128ClientLTPK, aesGcm128ClientLTPK.length - 16, aesGcm128ClientLTPK.length)); }}); byte[] pairSetupPin3ResponseBytes = AuthUtils.postData(socket, "/pair-setup-pin", "application/x-apple-binary-plist", pairSetupPinRequestData); NSDictionary pairSetupPin3Response = (NSDictionary) PropertyListParser.parse(pairSetupPin3ResponseBytes); if (pairSetupPin3Response.containsKey("epk") && pairSetupPin3Response.containsKey("authTag")) { byte[] epk = ((NSData) pairSetupPin3Response.get("epk")).bytes(); byte[] authTag = ((NSData) pairSetupPin3Response.get("authTag")).bytes(); return new PairSetupPin3Response(epk, authTag); } throw new Exception(); }
@Override public OutputStream getOutputStream() { random.nextBytes(nonce); try { cipher.init(Cipher.ENCRYPT_MODE, signingKey, new GCMParameterSpec(tagByteLen << 3, nonce)); } catch (InvalidKeyException | InvalidAlgorithmParameterException ex) { throw new IllegalStateException(ex); } return outputStream; }
@Test public final void test256bitKey() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { SecureRandom sr = SecureRandom.getInstanceStrong(); byte[] nonce = new byte[16]; sr.nextBytes(nonce); KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(256); byte[] key = keygen.generateKey().getEncoded(); byte[] data = new byte[256]; sr.nextBytes(data); Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding"); GCMParameterSpec paramSpec = new GCMParameterSpec(128, nonce); try { cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), paramSpec); cipher.doFinal(data); } catch (InvalidKeyException e) { throw new InterledgerRuntimeException("Error loading 256bit key. " + "Likley cause is missing Unlimited Strength Jurisdiction Policy Files.", e); } }