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

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

Introduction

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

Prototype

public GCMBlockCipher(BlockCipher c) 

Source Link

Usage

From source file:ECToken3.java

License:Open Source License

public static final String encryptv3(String key, String input) throws java.io.UnsupportedEncodingException,
        java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException,
        java.security.InvalidKeyException, javax.crypto.IllegalBlockSizeException,
        javax.crypto.BadPaddingException, java.security.InvalidAlgorithmParameterException {

    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| Encrypt\n");
    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| key:                   %s\n", key);
    //System.out.format("| token:                 %s\n", input);

    //----------------------------------------------------
    // Get SHA-256 of key
    //----------------------------------------------------
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(key.getBytes("ASCII"));
    byte[] keyDigest = md.digest();

    //----------------------------------------------------
    // Get Random IV
    //----------------------------------------------------
    SecureRandom random = new SecureRandom();
    byte[] ivBytes = new byte[12];
    random.nextBytes(ivBytes);/*from w  w w  . j  av  a  2s  .  c om*/

    //----------------------------------------------------
    // Encrypt
    //----------------------------------------------------
    AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    cipher.init(true, new AEADParameters(new KeyParameter(keyDigest), MAC_SIZE_BITS, ivBytes));
    byte[] inputBytes = input.getBytes("ASCII");

    byte[] enc = new byte[cipher.getOutputSize(inputBytes.length)];

    try {
        int res = cipher.processBytes(inputBytes, 0, inputBytes.length, enc, 0);
        cipher.doFinal(enc, res);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    byte[] ivPlusCipherText = new byte[ivBytes.length + enc.length];
    System.arraycopy(ivBytes, 0, ivPlusCipherText, 0, ivBytes.length);
    System.arraycopy(enc, 0, ivPlusCipherText, ivBytes.length, enc.length);

    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| iv:                    %s\n", bytesToHex(ivBytes));
    //System.out.format("| ciphertext:            %s\n", bytesToHex(Arrays.copyOfRange(enc, 0, enc.length - 16)));
    //System.out.format("| tag:                   %s\n", bytesToHex(Arrays.copyOfRange(enc, enc.length - 16, enc.length)));
    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| token:                 %s\n", bytesToHex(ivPlusCipherText));
    //System.out.format("+-------------------------------------------------------------\n");

    String result = null;
    byte[] temp = null;
    Base64 encoder = new Base64(0, temp, true);
    byte[] encodedBytes = encoder.encode(ivPlusCipherText);
    String encodedStr = new String(encodedBytes, "ASCII").trim();
    String encodedStrTrim = encodedStr.trim();
    return encodedStr.trim();
}

From source file:ECToken3.java

License:Open Source License

public static final String decryptv3(String key, String input) throws java.io.UnsupportedEncodingException,
        java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException,
        java.security.InvalidKeyException, javax.crypto.IllegalBlockSizeException,
        javax.crypto.BadPaddingException, java.security.InvalidAlgorithmParameterException {

    //----------------------------------------------------
    // Base64 decode
    //----------------------------------------------------
    String result = null;/*  w  ww.j  a va 2  s.c o  m*/
    Base64 encoder = new Base64(true);
    byte[] inputBytes = encoder.decode(input.getBytes("ASCII"));

    //----------------------------------------------------
    // Get SHA-256 of key
    //----------------------------------------------------
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(key.getBytes("ASCII"));
    byte[] keyDigest = md.digest();

    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| Decrypt\n");
    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| key:                   %s\n", key);
    //System.out.format("| token:                 %s\n", input);

    //----------------------------------------------------
    // Rip up the ciphertext
    //----------------------------------------------------
    byte[] ivBytes = new byte[12];
    ivBytes = Arrays.copyOfRange(inputBytes, 0, ivBytes.length);

    byte[] cipherBytes = new byte[inputBytes.length - ivBytes.length];
    cipherBytes = Arrays.copyOfRange(inputBytes, ivBytes.length, inputBytes.length);

    //----------------------------------------------------
    // Decrypt
    //----------------------------------------------------
    AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    cipher.init(false, new AEADParameters(new KeyParameter(keyDigest), MAC_SIZE_BITS, ivBytes));

    //System.out.format("+-------------------------------------------------------------\n");
    //System.out.format("| iv:                    %s\n", bytesToHex(ivBytes));
    //System.out.format("| ciphertext:            %s\n", bytesToHex(Arrays.copyOfRange(cipherBytes, 0, cipherBytes.length - 16)));
    //System.out.format("| tag:                   %s\n", bytesToHex(Arrays.copyOfRange(cipherBytes, cipherBytes.length - 16, cipherBytes.length)));
    //System.out.format("+-------------------------------------------------------------\n");

    byte[] dec = new byte[cipher.getOutputSize(cipherBytes.length)];

    try {
        int res = cipher.processBytes(cipherBytes, 0, cipherBytes.length, dec, 0);
        cipher.doFinal(dec, res);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    //System.out.format("token: %s\n", new String(dec, "ASCII"));
    return new String(dec, "ASCII");
}

From source file:at.archistar.crypto.symmetric.AESGCMEncryptor.java

@Override
public byte[] encrypt(byte[] data, byte[] randomKeyBytes) throws IOException, InvalidKeyException,
        InvalidAlgorithmParameterException, InvalidCipherTextException, ImpossibleException {

    AEADBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
    cipher.init(true, new AEADParameters(new KeyParameter(randomKeyBytes), 128, randomIvBytes));
    return cipherData(cipher, data);
}

From source file:at.archistar.crypto.symmetric.AESGCMEncryptor.java

@Override
public byte[] decrypt(byte[] data, byte[] randomKey)
        throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, IllegalStateException,
        InvalidCipherTextException, ImpossibleException {

    AEADBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
    cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIvBytes));
    return cipherData(cipher, data);
}

From source file:com.github.horrorho.inflatabledonkey.cache.StreamCryptor.java

License:Open Source License

public CipherOutputStream newCipherOutputStream(OutputStream os, byte[] password) throws IOException {
    byte[] salt = randomBytes(saltLength);
    byte[] nonce = randomBytes(nonceLength);
    os.write(salt);//from  w  w  w. j a  v  a2 s .  c  om
    os.write(nonce);
    byte[] dk = kdf.apply(password, salt);
    GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce);
    cipher.init(true, parameters);
    return new CipherOutputStream(os, cipher);
}

From source file:com.github.horrorho.inflatabledonkey.cache.StreamCryptor.java

License:Open Source License

public CipherInputStream newCipherInputStream(InputStream is, byte[] password) throws IOException {
    byte[] salt = IOUtils.readFully(is, saltLength);
    byte[] nonce = IOUtils.readFully(is, nonceLength);
    byte[] dk = kdf.apply(password, salt);
    GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine());
    AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce);
    cipher.init(false, parameters);/*from   w  w  w  . jav  a 2 s.  c  o m*/
    return new CipherInputStream(is, cipher);
}

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

License:Open Source License

/**
 * Returns decrypted data.//from   w ww  .ja v  a2 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 {//from  w ww.  ja v  a2 s .  com
        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  w w. 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 {//ww  w  . ja  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);
    }
}