Example usage for org.bouncycastle.crypto.modes GCMBlockCipher processBytes

List of usage examples for org.bouncycastle.crypto.modes GCMBlockCipher processBytes

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.modes GCMBlockCipher processBytes.

Prototype

public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException 

Source Link

Usage

From source file:com.github.horrorho.inflatabledonkey.crypto.AESGCM.java

License:Open Source License

/**
 * Returns decrypted data.//www . ja  v  a 2 s  . co m
 *
 * @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. jav a  2s.  co m
        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 {//from   w  ww. j a  v  a 2 s  . c  o 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 av a2  s.  co 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 www. java2 s .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}.//from  www . j a  v  a  2  s .  c  om
 * @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;//from  w w  w. ja  v a2s  . c om
}

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;// w  ww .jav a 2s  .com
}

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   www.java 2  s .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;/*  www . j a  va  2s. 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;
}