List of usage examples for org.bouncycastle.crypto.modes GCMBlockCipher getOutputSize
public int getOutputSize(int len)
From source file:com.github.horrorho.inflatabledonkey.crypto.AESGCM.java
License:Open Source License
/** * Returns decrypted data.//ww w . j av a 2 s . c om * * @param key * @param nonce nonce/ IV * @param header * @param encryptedData * @param tag * @param optional optional AADBytes (post header) * @return decrypted data * @throws IllegalArgumentException on decryption exceptions * @throws NullPointerException on null arguments */ public static byte[] decrypt(byte[] key, byte[] nonce, byte[] header, byte[] encryptedData, byte[] tag, Optional<byte[]> optional) { try { GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine()); AEADParameters parameters = new AEADParameters(new KeyParameter(key), tag.length * 8, nonce, header); cipher.init(false, parameters); if (optional.isPresent()) { byte[] aadBytes = optional.get(); cipher.processAADBytes(aadBytes, 0, aadBytes.length); } byte[] out = new byte[cipher.getOutputSize(encryptedData.length + tag.length)]; int pos = cipher.processBytes(encryptedData, 0, encryptedData.length, out, 0); pos += cipher.processBytes(tag, 0, tag.length, out, pos); pos += cipher.doFinal(out, pos); return Arrays.copyOf(out, pos); } catch (IllegalStateException | InvalidCipherTextException ex) { throw new IllegalStateException("GCM decrypt error", ex); } }
From source file:com.github.horrorho.inflatabledonkey.crypto.GCMDataB.java
License:Open Source License
public static byte[] decrypt(byte[] key, byte[] data) { // TODO utilize GCMAES#decrypt method try {// w w w. j a v a 2 s . c om if (data.length < NONCE_LENGTH + TAG_LENGTH) { throw new IllegalArgumentException("data packet too short"); } int cipherTextLength = data.length - NONCE_LENGTH - TAG_LENGTH; byte[] nonce = Arrays.copyOf(data, NONCE_LENGTH); GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine()); AEADParameters parameters = new AEADParameters(new KeyParameter(key), TAG_LENGTH * 8, nonce); cipher.init(false, parameters); byte[] out = new byte[cipher.getOutputSize(cipherTextLength + TAG_LENGTH)]; int pos = cipher.processBytes(data, NONCE_LENGTH, data.length - NONCE_LENGTH, out, 0); pos += cipher.doFinal(out, pos); return Arrays.copyOf(out, pos); } catch (IllegalStateException | InvalidCipherTextException ex) { throw new IllegalArgumentException(ex); } }
From source file:com.netflix.msl.crypto.JsonWebEncryptionCryptoContext.java
License:Open Source License
@Override public byte[] wrap(final byte[] data) throws MslCryptoException { // Create the header. final String header; try {/* ww w . j a v a2s . co m*/ header = new JSONStringer().object().key(KEY_ALGORITHM).value(algo.toString()).key(KEY_ENCRYPTION) .value(enc.name()).endObject().toString(); } catch (final JSONException e) { throw new MslCryptoException(MslError.JWE_ENCODE_ERROR, e); } // Determine algorithm byte lengths. final int keylen, ivlen, atlen; if (Encryption.A128GCM.equals(enc)) { keylen = A128_GCM_KEY_LENGTH; ivlen = A128_GCM_IV_LENGTH; atlen = A128_GCM_AT_LENGTH; } else if (Encryption.A256GCM.equals(enc)) { keylen = A256_GCM_KEY_LENGTH; ivlen = A256_GCM_IV_LENGTH; atlen = A256_GCM_AT_LENGTH; } else { throw new MslCryptoException(MslError.UNSUPPORTED_JWE_ALGORITHM, enc.name()); } // Generate the key and IV. final Random random = ctx.getRandom(); final byte[] key = new byte[keylen]; random.nextBytes(key); final KeyParameter cek = new KeyParameter(key); final byte[] iv = new byte[ivlen]; random.nextBytes(iv); // Encrypt the CEK. final byte[] ecek = cekCryptoContext.encrypt(cek.getKey()); // Base64-encode the data. final String headerB64 = JsonUtils.b64urlEncode(header.getBytes(UTF_8)); final String ecekB64 = JsonUtils.b64urlEncode(ecek); final String ivB64 = JsonUtils.b64urlEncode(iv); // Create additional authenticated data. final String aad = headerB64 + "." + ecekB64 + "." + ivB64; // TODO: AES-GCM is not available via the JCE. // // Create and initialize the cipher for encryption. final GCMBlockCipher plaintextCipher = new GCMBlockCipher(new AESEngine()); final AEADParameters params = new AEADParameters(cek, atlen, iv, aad.getBytes(UTF_8)); plaintextCipher.init(true, params); // Encrypt the plaintext. final byte[] ciphertextATag; try { final int clen = plaintextCipher.getOutputSize(data.length); ciphertextATag = new byte[clen]; // Encrypt the plaintext and get the resulting ciphertext length // which will be used for the authentication tag offset. final int offset = plaintextCipher.processBytes(data, 0, data.length, ciphertextATag, 0); // Append the authentication tag. plaintextCipher.doFinal(ciphertextATag, offset); } catch (final IllegalStateException e) { throw new MslCryptoException(MslError.WRAP_ERROR, e); } catch (final InvalidCipherTextException e) { throw new MslInternalException("Invalid ciphertext not expected when encrypting.", e); } // Split the result into the ciphertext and authentication tag. final byte[] ciphertext = Arrays.copyOfRange(ciphertextATag, 0, ciphertextATag.length - atlen / Byte.SIZE); final byte[] at = Arrays.copyOfRange(ciphertextATag, ciphertext.length, ciphertextATag.length); // Base64-encode the ciphertext and authentication tag. final String ciphertextB64 = JsonUtils.b64urlEncode(ciphertext); final String atB64 = JsonUtils.b64urlEncode(at); // Envelope the data. switch (format) { case JWE_CS: { final String serialization = aad + "." + ciphertextB64 + "." + atB64; return serialization.getBytes(UTF_8); } case JWE_JS: { try { // Create recipients array. final JSONArray recipients = new JSONArray(); final JSONObject recipient = new JSONObject(); recipient.put(KEY_HEADER, headerB64); recipient.put(KEY_ENCRYPTED_KEY, ecekB64); recipient.put(KEY_INTEGRITY_VALUE, atB64); recipients.put(recipient); // Create JSON serialization. final JSONObject serialization = new JSONObject(); serialization.put(KEY_RECIPIENTS, recipients); serialization.put(KEY_INITIALIZATION_VECTOR, ivB64); serialization.put(KEY_CIPHERTEXT, ciphertextB64); return serialization.toString().getBytes(UTF_8); } catch (final JSONException e) { throw new MslCryptoException(MslError.JWE_ENCODE_ERROR, e); } } default: throw new MslCryptoException(MslError.UNSUPPORTED_JWE_SERIALIZATION, format.name()); } }
From source file:com.netflix.msl.crypto.JsonWebEncryptionCryptoContext.java
License:Open Source License
@Override public byte[] unwrap(final byte[] data) throws MslCryptoException { // Parse the serialization. final String serialization = new String(data, UTF_8); final String headerB64, ecekB64, ivB64; final byte[] ciphertext, at; if (data[0] == '{') { try {/*from w w w . j a v a 2 s . c o m*/ final JSONObject serializationJo = new JSONObject(serialization); ivB64 = serializationJo.getString(KEY_INITIALIZATION_VECTOR); ciphertext = JsonUtils.b64urlDecode(serializationJo.getString(KEY_CIPHERTEXT)); // TODO: For now, we only support one recipient. final JSONArray recipients = serializationJo.getJSONArray(KEY_RECIPIENTS); final JSONObject recipient = recipients.getJSONObject(0); headerB64 = recipient.getString(KEY_HEADER); ecekB64 = recipient.getString(KEY_ENCRYPTED_KEY); at = JsonUtils.b64urlDecode(recipient.getString(KEY_INTEGRITY_VALUE)); } catch (final JSONException e) { throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization, e); } } else { // Separate the compact serialization. final String[] parts = serialization.split("\\."); if (parts.length != 5) throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization); // Extract the data from the serialization. headerB64 = parts[0]; ecekB64 = parts[1]; ivB64 = parts[2]; ciphertext = JsonUtils.b64urlDecode(parts[3]); at = JsonUtils.b64urlDecode(parts[4]); } // Decode header, encrypted content encryption key, and IV. final byte[] headerBytes = JsonUtils.b64urlDecode(headerB64); final byte[] ecek = JsonUtils.b64urlDecode(ecekB64); final byte[] iv = JsonUtils.b64urlDecode(ivB64); // Verify data. if (headerBytes == null || headerBytes.length == 0 || ecek == null || ecek.length == 0 || iv == null || iv.length == 0 || ciphertext == null || ciphertext.length == 0 || at == null || at.length == 0) { throw new MslCryptoException(MslError.JWE_PARSE_ERROR, serialization); } // Reconstruct and parse the header. final String header = new String(headerBytes, UTF_8); final Algorithm algo; final Encryption enc; try { final JSONObject headerJo = new JSONObject(header); final String algoName = headerJo.getString(KEY_ALGORITHM); try { algo = Algorithm.fromString(algoName); } catch (final IllegalArgumentException e) { throw new MslCryptoException(MslError.JWE_PARSE_ERROR, algoName, e); } final String encName = headerJo.getString(KEY_ENCRYPTION); try { enc = Encryption.valueOf(encName); } catch (final IllegalArgumentException e) { throw new MslCryptoException(MslError.JWE_PARSE_ERROR, encName, e); } } catch (final JSONException e) { throw new MslCryptoException(MslError.JWE_PARSE_ERROR, header, e); } // Confirm header matches. if (!this.algo.equals(algo) || !this.enc.equals(enc)) throw new MslCryptoException(MslError.JWE_ALGORITHM_MISMATCH, header); // Decrypt the CEK. final KeyParameter cek; try { final byte[] cekBytes = cekCryptoContext.decrypt(ecek); cek = new KeyParameter(cekBytes); } catch (final ArrayIndexOutOfBoundsException e) { // Thrown if the encrypted content encryption key is an invalid // length. throw new MslCryptoException(MslError.INVALID_SYMMETRIC_KEY, e); } // Create additional authenticated data. final String aad = headerB64 + "." + ecekB64 + "." + ivB64; // Determine algorithm byte lengths. final int keylen, atlen; if (Encryption.A128GCM.equals(enc)) { keylen = A128_GCM_KEY_LENGTH; atlen = A128_GCM_AT_LENGTH; } else if (Encryption.A256GCM.equals(enc)) { keylen = A256_GCM_KEY_LENGTH; atlen = A256_GCM_AT_LENGTH; } else { throw new MslCryptoException(MslError.UNSUPPORTED_JWE_ALGORITHM, enc.name()); } // Verify algorithm parameters. if (cek.getKey().length != keylen) throw new MslCryptoException(MslError.INVALID_SYMMETRIC_KEY, "content encryption key length: " + cek.getKey().length); if (at.length != atlen / Byte.SIZE) throw new MslCryptoException(MslError.INVALID_ALGORITHM_PARAMS, "authentication tag length: " + at.length); // TODO: AES-GCM is not available via the JCE. // // Create and initialize the cipher for decryption. final GCMBlockCipher plaintextCipher = new GCMBlockCipher(new AESEngine()); final AEADParameters params = new AEADParameters(cek, atlen, iv, aad.getBytes(UTF_8)); plaintextCipher.init(false, params); // Decrypt the ciphertext. try { // Reconstruct the ciphertext and authentication tag. final byte[] ciphertextAtag = Arrays.copyOf(ciphertext, ciphertext.length + at.length); System.arraycopy(at, 0, ciphertextAtag, ciphertext.length, at.length); int plen = plaintextCipher.getOutputSize(ciphertextAtag.length); byte[] plaintext = new byte[plen]; // Decrypt the ciphertext and get the resulting plaintext length // which will be used for the authentication tag offset. int offset = plaintextCipher.processBytes(ciphertextAtag, 0, ciphertextAtag.length, plaintext, 0); // Verify the authentication tag. plaintextCipher.doFinal(plaintext, offset); return plaintext; } catch (final IllegalStateException e) { throw new MslCryptoException(MslError.UNWRAP_ERROR, e); } catch (final InvalidCipherTextException e) { throw new MslCryptoException(MslError.UNWRAP_ERROR, e); } catch (final ArrayIndexOutOfBoundsException e) { // Thrown if the ciphertext is an invalid length. throw new MslCryptoException(MslError.UNWRAP_ERROR, e); } }
From source file:com.nimbusds.jose.crypto.impl.LegacyAESGCM.java
License:Apache License
/** * Encrypts the specified plain text using AES/GCM/NoPadding. * * @param secretKey The AES key. Must not be {@code null}. * @param plainText The plain text. Must not be {@code null}. * @param iv The initialisation vector (IV). Must not be * {@code null}./*from w ww .j a va2s .c o m*/ * @param authData The authenticated data. Must not be {@code null}. * * @return The authenticated cipher text. * * @throws JOSEException If encryption failed. */ public static AuthenticatedCipherText encrypt(final SecretKey secretKey, final byte[] iv, final byte[] plainText, final byte[] authData) throws JOSEException { // Initialise AES/GCM cipher for encryption GCMBlockCipher cipher = createAESGCMCipher(secretKey, true, iv, authData); // Prepare output buffer int outputLength = cipher.getOutputSize(plainText.length); byte[] output = new byte[outputLength]; // Produce cipher text int outputOffset = cipher.processBytes(plainText, 0, plainText.length, output, 0); // Produce authentication tag try { outputOffset += cipher.doFinal(output, outputOffset); } catch (InvalidCipherTextException e) { throw new JOSEException("Couldn't generate GCM authentication tag: " + e.getMessage(), e); } // Split output into cipher text and authentication tag int authTagLength = AUTH_TAG_BIT_LENGTH / 8; byte[] cipherText = new byte[outputOffset - authTagLength]; byte[] authTag = new byte[authTagLength]; System.arraycopy(output, 0, cipherText, 0, cipherText.length); System.arraycopy(output, outputOffset - authTagLength, authTag, 0, authTag.length); return new AuthenticatedCipherText(cipherText, authTag); }
From source file:com.nimbusds.jose.crypto.impl.LegacyAESGCM.java
License:Apache License
/** * Decrypts the specified cipher text using AES/GCM/NoPadding. * * @param secretKey The AES key. Must not be {@code null}. * @param iv The initialisation vector (IV). Must not be * {@code null}./*w ww. java 2s .co m*/ * @param cipherText The cipher text. Must not be {@code null}. * @param authData The authenticated data. Must not be {@code null}. * @param authTag The authentication tag. Must not be {@code null}. * * @return The decrypted plain text. * * @throws JOSEException If decryption failed. */ public static byte[] decrypt(final SecretKey secretKey, final byte[] iv, final byte[] cipherText, final byte[] authData, final byte[] authTag) throws JOSEException { // Initialise AES/GCM cipher for decryption GCMBlockCipher cipher = createAESGCMCipher(secretKey, false, iv, authData); // Join cipher text and authentication tag to produce cipher input byte[] input = new byte[cipherText.length + authTag.length]; System.arraycopy(cipherText, 0, input, 0, cipherText.length); System.arraycopy(authTag, 0, input, cipherText.length, authTag.length); int outputLength = cipher.getOutputSize(input.length); byte[] output = new byte[outputLength]; // Decrypt int outputOffset = cipher.processBytes(input, 0, input.length, output, 0); // Validate authentication tag try { outputOffset += cipher.doFinal(output, outputOffset); } catch (InvalidCipherTextException e) { throw new JOSEException("Couldn't validate GCM authentication tag: " + e.getMessage(), e); } return output; }
From source file:com.skplanet.jose.jwa.crypto.CryptoUtils.java
License:Open Source License
public static byte[] aesGcmEncrypt(Transformation transformation, byte[] raw, byte[] secret, int atLength, byte[] iv, byte[] aad) throws Exception { BlockCipher blockCipher = new AESEngine(); blockCipher.init(true, new KeyParameter(new SecretKeySpec(secret, "AES").getEncoded())); GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher); aGCMBlockCipher.init(true, new AEADParameters(new KeyParameter(secret), atLength, iv, aad)); int len = aGCMBlockCipher.getOutputSize(raw.length); byte[] out = new byte[len]; int outOff = aGCMBlockCipher.processBytes(raw, 0, raw.length, out, 0); aGCMBlockCipher.doFinal(out, outOff); return out;/*ww w .jav a 2s . co m*/ }
From source file:com.skplanet.jose.jwa.crypto.CryptoUtils.java
License:Open Source License
public static byte[] aesGcmDecrypt(Transformation transformation, byte[] encryptedData, byte[] secret, int atLength, byte[] iv, byte[] aad) throws Exception { BlockCipher blockCipher = new AESEngine(); blockCipher.init(false, new KeyParameter(new SecretKeySpec(secret, "AES").getEncoded())); GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher); aGCMBlockCipher.init(false, new AEADParameters(new KeyParameter(secret), atLength, iv, aad)); int len = aGCMBlockCipher.getOutputSize(encryptedData.length); byte[] out = new byte[len]; int outOff = aGCMBlockCipher.processBytes(encryptedData, 0, encryptedData.length, out, 0); aGCMBlockCipher.doFinal(out, outOff); return out;/*from w w w . ja v a2 s . co m*/ }
From source file:COSE.EncryptCommon.java
private void AES_GCM_Decrypt(AlgorithmID alg, byte[] rgbKey) throws CoseException, InvalidCipherTextException { GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine(), new BasicGCMMultiplier()); CBORObject cn = FindAttribute(HeaderKeys.IV); if (cn == null) throw new CoseException("Missing IV during decryption"); if (cn.getType() != CBORType.ByteString) throw new CoseException("IV is incorrectly formed"); if (cn.GetByteString().length != 96 / 8) throw new CoseException("IV size is incorrect"); if (rgbKey.length != alg.getKeySize() / 8) throw new CoseException("Missing IV during decryption"); KeyParameter contentKey = new KeyParameter(rgbKey); AEADParameters parameters = new AEADParameters(contentKey, 128, cn.GetByteString(), getAADBytes()); cipher.init(false, parameters);/*from w w w. j a v a2s. c o m*/ byte[] C = new byte[cipher.getOutputSize(rgbEncrypt.length)]; int length = cipher.processBytes(rgbEncrypt, 0, rgbEncrypt.length, C, 0); length += cipher.doFinal(C, length); rgbContent = C; }
From source file:COSE.EncryptCommon.java
private void AES_GCM_Encrypt(AlgorithmID alg, byte[] rgbKey) throws CoseException, IllegalStateException, InvalidCipherTextException { GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine(), new BasicGCMMultiplier()); if (rgbKey.length != alg.getKeySize() / 8) throw new CoseException("Key Size is incorrect"); KeyParameter contentKey = new KeyParameter(rgbKey); CBORObject cn = FindAttribute(HeaderKeys.IV); byte[] IV;//w ww . ja va2 s. c o m if (cn == null) { IV = new byte[96 / 8]; random.nextBytes(IV); AddUnprotected(HeaderKeys.IV, CBORObject.FromObject(IV)); } else { if (cn.getType() != CBORType.ByteString) throw new CoseException("IV is incorrectly formed"); if (cn.GetByteString().length != 96 / 8) throw new CoseException("IV size is incorrect"); IV = cn.GetByteString(); } AEADParameters parameters = new AEADParameters(contentKey, 128, IV, getAADBytes()); cipher.init(true, parameters); byte[] C = new byte[cipher.getOutputSize(rgbContent.length)]; int length = cipher.processBytes(rgbContent, 0, rgbContent.length, C, 0); length += cipher.doFinal(C, length); rgbEncrypt = C; }