com.skplanet.jose.jwa.crypto.CryptoUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.skplanet.jose.jwa.crypto.CryptoUtils.java

Source

/*
 * Copyright (c) 2015 SK PLANET. ALL Rights Reserved.
 *
 * Syrup Pay Jose Library
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.skplanet.jose.jwa.crypto;

import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.AESWrapEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

public class CryptoUtils {
    public static byte[] aesEncrypt(Transformation transformation, byte[] raw, byte[] secret, byte[] iv)
            throws Exception {
        Cipher cipher = Cipher.getInstance(transformation.getValue());
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secret, transformation.getAlgorithm()),
                new IvParameterSpec(iv));
        return cipher.doFinal(raw);
    }

    public static byte[] aesDecrypt(Transformation transformation, byte[] encryptedData, byte[] secret, byte[] iv)
            throws Exception {
        Cipher cipher = Cipher.getInstance(transformation.getValue());
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secret, transformation.getAlgorithm()),
                new IvParameterSpec(iv));
        return cipher.doFinal(encryptedData);
    }

    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;
    }

    //   public static byte[] aesGcmEncrypt(Transformation transformation, byte[] raw, byte[] secret, int atLength, byte[] iv, byte[] aad) throws Exception {
    //      Cipher cipher = Cipher.getInstance(transformation.getValue());
    //      cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secret, transformation.getAlgorithm()),
    //            new GCMParameterSpec(atLength, iv));
    //      cipher.updateAAD(aad);
    //      return cipher.doFinal(raw);
    //   }

    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;
    }

    //   public static byte[] aesGcmDecrypt(Transformation transformation, byte[] encryptedData, byte[] secret, int atLength, byte[] iv, byte[] aad) throws Exception {
    //      Cipher cipher = Cipher.getInstance(transformation.getValue());
    //      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secret, transformation.getAlgorithm()),
    //            new GCMParameterSpec(atLength, iv));
    //      cipher.updateAAD(aad);
    //      return cipher.doFinal(encryptedData);
    //   }

    public static byte[] rsaEncrypt(Transformation transformation, byte[] raw, PublicKey key) throws Exception {
        Cipher cipher = Cipher.getInstance(transformation.getValue());
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(raw);
    }

    public static byte[] rsaDecrypt(Transformation transformation, byte[] encrypted, PrivateKey key)
            throws Exception {
        Cipher cipher = null;

        try {
            cipher = Cipher.getInstance(transformation.getValue());
        } catch (NoSuchAlgorithmException e) {
            if (Security.getProvider("BC") == null) {
                Security.addProvider(new BouncyCastleProvider());
            }

            cipher = Cipher.getInstance(transformation.getValue());
        }

        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(encrypted);
    }

    public static RSAPublicKey generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent)
            throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPublicKey) keyFactory.generatePublic(new RSAPublicKeySpec(modulus, publicExponent));
    }

    public static PublicKey generatePublicKey(KeyAlgorithm algorithms, byte[] pKey) throws Exception {
        X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(pKey);
        KeyFactory keyFactory = KeyFactory.getInstance(algorithms.getValue());
        return keyFactory.generatePublic(x509Spec);
    }

    public static RSAPrivateKey generateRsaPrivateKey(BigInteger modulus, BigInteger privateExponent)
            throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPrivateKey) keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
    }

    public static PrivateKey generatePrivateKey(KeyAlgorithm algorithms, byte[] pKey) throws Exception {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pKey);
        KeyFactory keyFactory = KeyFactory.getInstance(algorithms.getValue());
        return keyFactory.generatePrivate(keySpec);
    }

    public static SecretKeySpec generateSymmetricKey(byte[] key, Algorithm algorithm) {
        return new SecretKeySpec(key, algorithm.getValue());
    }

    public static KeyPair generateRsaKeyPair(int keySize, BigInteger publicExponent) throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keySize, publicExponent);
        keyGen.initialize(spec);
        return keyGen.generateKeyPair();
    }

    public static byte[] hmac(Transformation transformation, byte[] raw, byte[] macKey)
            throws NoSuchAlgorithmException, InvalidKeyException {
        Mac hmac = Mac.getInstance(transformation.getValue());
        hmac.init(new SecretKeySpec(macKey, transformation.getAlgorithm()));
        return hmac.doFinal(raw);
    }

    public static byte[] asymmetricSignature(Transformation transformation, Key key, byte[] bytes)
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance(transformation.getValue());
        signature.initSign((PrivateKey) key);
        signature.update(bytes);

        return signature.sign();
    }

    public static boolean asymmetricSignatureVerify(Transformation transformation, Key key, byte[] signingBytes,
            byte[] expectedBytes) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature verifier = Signature.getInstance(transformation.getValue());
        verifier.initVerify((PublicKey) key);
        verifier.update(signingBytes);
        return verifier.verify(expectedBytes);
    }

    public static byte[] KeyWrap(Transformation transformation, byte[] symmetricKey, byte[] cek) {
        AESWrapEngine engine = new AESWrapEngine();
        CipherParameters param = new KeyParameter(
                new SecretKeySpec(symmetricKey, transformation.getAlgorithm()).getEncoded());
        engine.init(true, param);
        return engine.wrap(cek, 0, cek.length);
    }

    /*
    public static byte[] KeyWrap(Transformation transformation, byte[] symmetricKey, byte[] cek)
     throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException,
     NoSuchProviderException {
       Cipher cipher = Cipher.getInstance("AESWrap");
       cipher.init(Cipher.WRAP_MODE, new SecretKeySpec(symmetricKey, transformation.getAlgorithm()));
       return cipher.wrap(new SecretKeySpec(cek, transformation.getAlgorithm()));
    }
    */

    public static byte[] keyUnwrap(Transformation transformation, byte[] symmetricKey, byte[] cek)
            throws Exception {
        AESWrapEngine engine = new AESWrapEngine();
        CipherParameters param = new KeyParameter(
                new SecretKeySpec(symmetricKey, transformation.getAlgorithm()).getEncoded());
        engine.init(false, param);
        return engine.unwrap(cek, 0, cek.length);
    }

    /*
    public static byte[] keyUnwrap(Transformation transformation, byte[] symmetricKey, byte[] cek) throws Exception {
       Cipher cipher = Cipher.getInstance("AESWrap");
       cipher.init(Cipher.UNWRAP_MODE, new SecretKeySpec(symmetricKey, transformation.getAlgorithm()));
       return cipher.unwrap(cek, transformation.getAlgorithm(), Cipher.SECRET_KEY).getEncoded();
    }
    */

    public static byte[] generatorKey(Transformation transformation, int size) throws NoSuchAlgorithmException {
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        KeyGenerator keyGenerator = KeyGenerator.getInstance(transformation.getAlgorithm());
        keyGenerator.init(size, secureRandom);

        SecretKey key = keyGenerator.generateKey();
        return key.getEncoded();
    }

    private static ECParameterSpec P256 = new ECParameterSpec(
            new EllipticCurve(
                    new ECFieldFp(
                            new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16)),
                    new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16),
                    new BigInteger("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", 16)),
            new ECPoint(new BigInteger("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 16),
                    new BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 16)),
            new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16), 1);

    public static ECPrivateKey generateEcPrivateKey(byte[] d) throws Exception {
        ECPrivateKey privateKey = null;

        try {
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            privateKey = (ECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(new BigInteger(d), P256));
        } catch (NoSuchAlgorithmException e) {
            if (Security.getProvider("BC") == null) {
                Security.addProvider(new BouncyCastleProvider());
            }

            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
            privateKey = (ECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(new BigInteger(d), P256));
        }

        return privateKey;
    }

    public static ECPublicKey generateEcPublicKey(byte[] x, byte[] y) throws Exception {
        ECPublicKey publicKey = null;

        ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(x), new BigInteger(y)),
                P256);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            publicKey = (ECPublicKey) keyFactory.generatePublic(ecPublicKeySpec);
        } catch (NoSuchAlgorithmException e) {
            if (Security.getProvider("BC") == null) {
                Security.addProvider(new BouncyCastleProvider());
            }

            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
            publicKey = (ECPublicKey) keyFactory.generatePublic(ecPublicKeySpec);
        }

        return publicKey;
    }
}