@Test public void testDecryptV1() throws Exception { String decrypted = crypto1.decryptSecret(V1_ENCRYPTED); assertThat(decrypted, is(TEXT)); }
@Override public String decryptSecret(String encryptedBase64) { byte[] encrypted = Base64.getDecoder().decode(encryptedBase64); Preconditions.checkArgument(encrypted.length >= WRAPPING_SIZE + GCM_TAG_LENGTH, "Bad size"); ByteBuffer buffer = ByteBuffer.wrap(encrypted); byte[] nameBytes = new byte[NAME_SIZE]; buffer.get(nameBytes); if (!Arrays.equals(NAME_BYTES, nameBytes)) { throw new IllegalArgumentException("Crypto engine mismatch"); } int version = buffer.getInt(); if (version != VERSION_1 && version != VERSION_2) { throw new IllegalArgumentException("Bad version"); } int term = buffer.getInt(); if (term != TERM) { throw new IllegalArgumentException("Bad term"); } byte[] nonce = new byte[GCM_NONCE_LENGTH]; buffer.get(nonce); Cipher cipher = cipher(Cipher.DECRYPT_MODE, sharedSecret, nonce); byte[] recordBytes; try { recordBytes = cipher.doFinal(encrypted, buffer.position(), buffer.remaining()); } catch (AEADBadTagException e) { throw new SecretCryptoException(e); } catch (IllegalBlockSizeException | BadPaddingException e) { throw Throwables.propagate(e); } ByteBuffer decryptedBuffer = ByteBuffer.wrap(recordBytes); int length = decryptedBuffer.getInt(); if (length < -1 || length > MAX_PLAINTEXT_LENGTH) { throw new IllegalArgumentException("Bad length"); } decryptedBuffer.limit(decryptedBuffer.position() + length); return UTF_8.decode(decryptedBuffer).toString(); }
AESGCMSecretCrypto implements SecretCrypto { @Override public String decryptSecret(String encryptedBase64) { byte[] encrypted = Base64.getDecoder().decode(encryptedBase64); Preconditions.checkArgument(encrypted.length >= WRAPPING_SIZE + GCM_TAG_LENGTH, "Bad size"); ByteBuffer buffer = ByteBuffer.wrap(encrypted); byte[] nameBytes = new byte[NAME_SIZE]; buffer.get(nameBytes); if (!Arrays.equals(NAME_BYTES, nameBytes)) { throw new IllegalArgumentException("Crypto engine mismatch"); } int version = buffer.getInt(); if (version != VERSION_1 && version != VERSION_2) { throw new IllegalArgumentException("Bad version"); } int term = buffer.getInt(); if (term != TERM) { throw new IllegalArgumentException("Bad term"); } byte[] nonce = new byte[GCM_NONCE_LENGTH]; buffer.get(nonce); Cipher cipher = cipher(Cipher.DECRYPT_MODE, sharedSecret, nonce); byte[] recordBytes; try { recordBytes = cipher.doFinal(encrypted, buffer.position(), buffer.remaining()); } catch (AEADBadTagException e) { throw new SecretCryptoException(e); } catch (IllegalBlockSizeException | BadPaddingException e) { throw Throwables.propagate(e); } ByteBuffer decryptedBuffer = ByteBuffer.wrap(recordBytes); int length = decryptedBuffer.getInt(); if (length < -1 || length > MAX_PLAINTEXT_LENGTH) { throw new IllegalArgumentException("Bad length"); } decryptedBuffer.limit(decryptedBuffer.position() + length); return UTF_8.decode(decryptedBuffer).toString(); } }
AESGCMSecretCrypto implements SecretCrypto { @Override public String decryptSecret(String encryptedBase64) { byte[] encrypted = Base64.getDecoder().decode(encryptedBase64); Preconditions.checkArgument(encrypted.length >= WRAPPING_SIZE + GCM_TAG_LENGTH, "Bad size"); ByteBuffer buffer = ByteBuffer.wrap(encrypted); byte[] nameBytes = new byte[NAME_SIZE]; buffer.get(nameBytes); if (!Arrays.equals(NAME_BYTES, nameBytes)) { throw new IllegalArgumentException("Crypto engine mismatch"); } int version = buffer.getInt(); if (version != VERSION_1 && version != VERSION_2) { throw new IllegalArgumentException("Bad version"); } int term = buffer.getInt(); if (term != TERM) { throw new IllegalArgumentException("Bad term"); } byte[] nonce = new byte[GCM_NONCE_LENGTH]; buffer.get(nonce); Cipher cipher = cipher(Cipher.DECRYPT_MODE, sharedSecret, nonce); byte[] recordBytes; try { recordBytes = cipher.doFinal(encrypted, buffer.position(), buffer.remaining()); } catch (AEADBadTagException e) { throw new SecretCryptoException(e); } catch (IllegalBlockSizeException | BadPaddingException e) { throw Throwables.propagate(e); } ByteBuffer decryptedBuffer = ByteBuffer.wrap(recordBytes); int length = decryptedBuffer.getInt(); if (length < -1 || length > MAX_PLAINTEXT_LENGTH) { throw new IllegalArgumentException("Bad length"); } decryptedBuffer.limit(decryptedBuffer.position() + length); return UTF_8.decode(decryptedBuffer).toString(); } AESGCMSecretCrypto(String sharedSecretBase64); }
AESGCMSecretCrypto implements SecretCrypto { @Override public String decryptSecret(String encryptedBase64) { byte[] encrypted = Base64.getDecoder().decode(encryptedBase64); Preconditions.checkArgument(encrypted.length >= WRAPPING_SIZE + GCM_TAG_LENGTH, "Bad size"); ByteBuffer buffer = ByteBuffer.wrap(encrypted); byte[] nameBytes = new byte[NAME_SIZE]; buffer.get(nameBytes); if (!Arrays.equals(NAME_BYTES, nameBytes)) { throw new IllegalArgumentException("Crypto engine mismatch"); } int version = buffer.getInt(); if (version != VERSION_1 && version != VERSION_2) { throw new IllegalArgumentException("Bad version"); } int term = buffer.getInt(); if (term != TERM) { throw new IllegalArgumentException("Bad term"); } byte[] nonce = new byte[GCM_NONCE_LENGTH]; buffer.get(nonce); Cipher cipher = cipher(Cipher.DECRYPT_MODE, sharedSecret, nonce); byte[] recordBytes; try { recordBytes = cipher.doFinal(encrypted, buffer.position(), buffer.remaining()); } catch (AEADBadTagException e) { throw new SecretCryptoException(e); } catch (IllegalBlockSizeException | BadPaddingException e) { throw Throwables.propagate(e); } ByteBuffer decryptedBuffer = ByteBuffer.wrap(recordBytes); int length = decryptedBuffer.getInt(); if (length < -1 || length > MAX_PLAINTEXT_LENGTH) { throw new IllegalArgumentException("Bad length"); } decryptedBuffer.limit(decryptedBuffer.position() + length); return UTF_8.decode(decryptedBuffer).toString(); } AESGCMSecretCrypto(String sharedSecretBase64); @Override String encryptSecret(String plainText); @Override String decryptSecret(String encryptedBase64); @Override String getName(); }
AESGCMSecretCrypto implements SecretCrypto { @Override public String decryptSecret(String encryptedBase64) { byte[] encrypted = Base64.getDecoder().decode(encryptedBase64); Preconditions.checkArgument(encrypted.length >= WRAPPING_SIZE + GCM_TAG_LENGTH, "Bad size"); ByteBuffer buffer = ByteBuffer.wrap(encrypted); byte[] nameBytes = new byte[NAME_SIZE]; buffer.get(nameBytes); if (!Arrays.equals(NAME_BYTES, nameBytes)) { throw new IllegalArgumentException("Crypto engine mismatch"); } int version = buffer.getInt(); if (version != VERSION_1 && version != VERSION_2) { throw new IllegalArgumentException("Bad version"); } int term = buffer.getInt(); if (term != TERM) { throw new IllegalArgumentException("Bad term"); } byte[] nonce = new byte[GCM_NONCE_LENGTH]; buffer.get(nonce); Cipher cipher = cipher(Cipher.DECRYPT_MODE, sharedSecret, nonce); byte[] recordBytes; try { recordBytes = cipher.doFinal(encrypted, buffer.position(), buffer.remaining()); } catch (AEADBadTagException e) { throw new SecretCryptoException(e); } catch (IllegalBlockSizeException | BadPaddingException e) { throw Throwables.propagate(e); } ByteBuffer decryptedBuffer = ByteBuffer.wrap(recordBytes); int length = decryptedBuffer.getInt(); if (length < -1 || length > MAX_PLAINTEXT_LENGTH) { throw new IllegalArgumentException("Bad length"); } decryptedBuffer.limit(decryptedBuffer.position() + length); return UTF_8.decode(decryptedBuffer).toString(); } AESGCMSecretCrypto(String sharedSecretBase64); @Override String encryptSecret(String plainText); @Override String decryptSecret(String encryptedBase64); @Override String getName();  }