Package org.jboss.aerogear.crypto

Source Code of org.jboss.aerogear.crypto.CryptoBox

/**
* JBoss, Home of Professional Open Source
* Copyright Red Hat, Inc., and individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.aerogear.crypto;

import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.jboss.aerogear.AeroGearCrypto;
import org.jboss.aerogear.crypto.encoders.Encoder;
import org.jboss.aerogear.crypto.keys.PrivateKey;

import javax.crypto.KeyAgreement;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;

import static org.jboss.aerogear.AeroGearCrypto.MINIMUM_SECRET_KEY_SIZE;
import static org.jboss.aerogear.AeroGearCrypto.TAG_LENGTH;
import static org.jboss.aerogear.crypto.Util.checkLength;
import static org.jboss.aerogear.crypto.Util.newBuffer;
import static org.jboss.aerogear.crypto.Util.newByteArray;

/**
* Class responsible for box and unbox crypto messages given the key
*/
public class CryptoBox {

    private byte[] key;
    private AEADBlockCipher cipher;
    private byte[] authData;

    /**
     * Initializes the box providing the secret key
     * @param key byte array
     */
    public CryptoBox(byte[] key) {
        checkLength(key, MINIMUM_SECRET_KEY_SIZE);
        this.cipher = BlockCipher.getInstance();
        this.key = key;

    }

    /**
     * Initializes the box providing the secret key
     * @param key reference to the PrivateKey
     */
    public CryptoBox(PrivateKey key) {
        this(key.toBytes());
    }

    /**
     * Initializes the box providing the secret key and encoder
     * @param key
     * @param encoder
     */
    public CryptoBox(String key, Encoder encoder) {
        this(encoder.decode(key));
    }

    /**
     * Initializes the box providing the key pair for asymmetric encryption
     * @param privateKey
     * @param publicKey
     */
    public CryptoBox(java.security.PrivateKey privateKey, PublicKey publicKey) {
        this.cipher = BlockCipher.getInstance();
        this.key = generateSecret(privateKey, publicKey);
        checkLength(key, MINIMUM_SECRET_KEY_SIZE);
    }

    private byte[] generateSecret(java.security.PrivateKey privateKey, PublicKey publicKey) {
        MessageDigest hash = null;
        KeyAgreement keyAgree = null;
        try {
            hash = MessageDigest.getInstance("SHA-256", AeroGearCrypto.PROVIDER);
            keyAgree = KeyAgreement.getInstance("ECDH", AeroGearCrypto.PROVIDER);
            keyAgree.init(privateKey);
            keyAgree.doPhase(publicKey, true);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            throw new RuntimeException("Fail: ", e);
        }

        return hash.digest(keyAgree.generateSecret());
    }

    /**
     * Given the IV, encrypt the provided data
     * @param IV initialization vector
     * @param message data to be encrypted
     * @return byte array with the cipher text
     * @throws RuntimeException
     */
    public byte[] encrypt(final byte[] IV, final byte[] message) throws RuntimeException {

        AEADParameters aeadParams = new AEADParameters(
                new KeyParameter(key), TAG_LENGTH,
                IV,
                authData);

        cipher.init(true, aeadParams);
        byte[] cipherText = newBuffer(cipher.getOutputSize(message.length));
        int outputOffset = cipher.processBytes(message, 0, message.length, cipherText, 0);

        try {
            cipher.doFinal(cipherText, outputOffset);
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException("Error: ", e);
        }

        return cipherText;
    }

    /**
     * Given the IV, encrypt and encode the provided data
     * @param IV initialization vector
     * @param message data to be encrypted
     * @param encoder encoder provided RAW or HEX
     * @return byte array with the cipher text
     */
    public byte[] encrypt(String IV, String message, Encoder encoder) {
        return encrypt(encoder.decode(IV), encoder.decode(message));
    }

    /**
     * Given the IV, decrypt the provided data
     * @param IV initialization vector
     * @param cipherText data to be decrypted
     * @return byte array with the plain text
     * @throws RuntimeException
     */
    public byte[] decrypt(byte[] IV, byte[] cipherText) throws RuntimeException {

        AEADParameters aeadParams = new AEADParameters(
                new KeyParameter(key), TAG_LENGTH,
                IV,
                authData);

        cipher.init(false, aeadParams);
        byte[] buffer = newByteArray(cipherText);
        byte[] plainText = newBuffer(cipher.getOutputSize(cipherText.length));
        int outputOffset = cipher.processBytes(buffer, 0, buffer.length, plainText, 0);

        try {
            cipher.doFinal(plainText, outputOffset);
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException("Error: ", e);
        }

        return plainText;
    }

    /**
     * Given the IV, decrypt the provided data
     * @param IV initialization vector
     * @param cipherText data to be decrypted
     * @param encoder encoder provided RAW or HEX
     * @return byte array with the plain text
     */
    public byte[] decrypt(String IV, String cipherText, Encoder encoder) {
        return decrypt(encoder.decode(IV), encoder.decode(cipherText));
    }

    //TODO
    public void updateAAD(byte[] authData) {
        this.authData = authData;
    }
}
TOP

Related Classes of org.jboss.aerogear.crypto.CryptoBox

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.