All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.zcltd.btg.sutil.encrypt.rsa.EncryptionRSA Maven / Gradle / Ivy

There is a newer version: 4.0.24
Show newest version
package cn.zcltd.btg.sutil.encrypt.rsa;

import cn.zcltd.btg.sutil.encrypt.Encryption;
import cn.zcltd.btg.sutil.EmptyUtil;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 带RSA的加密解密组件
 * RSA加密解密
 */
public class EncryptionRSA extends Encryption {
    public static final String ALGORITHM_RSA = "RSA";
    public static final String SIGN_ALGORITHMS_MD5 = "MD5WithRSA";
    public static final String SIGN_ALGORITHMS_SHA1 = "SHA1WithRSA";

    /**
     * 生成RSA秘钥
     *
     * @param keySize 秘钥长度
     * @param seed    种子
     * @return RSA秘钥信息
     */
    public static EncryptionKeyRSA generatorRSAKey(int keySize, byte[] seed) {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
            SecureRandom secureRandom;
            if (EmptyUtil.isNotEmpty(seed)) {
                secureRandom = new SecureRandom(seed);
            } else {
                secureRandom = new SecureRandom();
            }
            keyPairGen.initialize(keySize, secureRandom);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

            EncryptionKeyRSA encryptionKeyRSA = new EncryptionKeyRSA(publicKey.getModulus(), publicKey.getPublicExponent(), privateKey.getPrivateExponent());
            encryptionKeyRSA.setPublicKey(publicKey.getEncoded());
            encryptionKeyRSA.setPrivateKey(privateKey.getEncoded());

            return encryptionKeyRSA;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成RSA秘钥
     *
     * @param keySize 秘钥长度
     * @return RSA秘钥信息
     */
    public static EncryptionKeyRSA generatorRSAKey(int keySize) {
        return generatorRSAKey(keySize, null);
    }

    /**
     * 使用模和指数生成RSA公钥
     * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA/None/NoPadding】
     *
     * @param modulus  模
     * @param exponent 指数
     * @return 公钥
     */
    public static RSAPublicKey parseRSAPublicKey(BigInteger modulus, BigInteger exponent) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将十六进制公钥字符串转换为公钥
     *
     * @param publicKeyHex 十六进制公钥字符串
     * @return 公钥
     */
    public static RSAPublicKey parseRSAPublicKeyFromHex(String publicKeyHex) {
        try {
            byte[] buffer = hexToBytes(publicKeyHex);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将base64公钥字符串转换为公钥
     *
     * @param publicKeyBase64 base64公钥字符串
     * @return 公钥
     */
    public static RSAPublicKey parseRSAPublicKeyFromBase64(String publicKeyBase64) {
        try {
            byte[] buffer = decryptBASE64(publicKeyBase64);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 使用模和指数生成RSA私钥
     * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
     * /None/NoPadding】
     *
     * @param modulus  模
     * @param exponent 指数
     * @return 私钥
     */
    public static RSAPrivateKey parseRSAPrivateKey(BigInteger modulus, BigInteger exponent) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exponent);
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将十六进制私钥字符串转换为私钥
     *
     * @param primaryKeyHex 十六进制私钥字符串
     * @return 私钥
     */
    public static RSAPrivateKey parseRSAPrivateKeyFromHex(String primaryKeyHex) {
        try {
            byte[] buffer = hexToBytes(primaryKeyHex);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将base64私钥字符串转换为私钥
     *
     * @param primaryKeyHex base64私钥字符串
     * @return 私钥
     */
    public static RSAPrivateKey parseRSAPrivateKeyFromBase64(String primaryKeyHex) {
        try {
            byte[] buffer = decryptBASE64(primaryKeyHex);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key  秘钥
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static byte[] encryptRSA(Key key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
            cipher.init(Cipher.ENCRYPT_MODE, key);

            int splitLength = ((RSAKey) key).getModulus().bitLength() / 8 - 11;
            byte[][] arrays = splitBytes(data, splitLength);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            for (byte[] array : arrays) {
                byte[] cache = cipher.doFinal(array);
                out.write(cache, 0, cache.length);
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            return encryptedData;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key  秘钥
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static String encryptRSAToHex(Key key, byte[] data) {
        return bytesToHex(encryptRSA(key, data));
    }

    /**
     * 加密
     *
     * @param key      秘钥
     * @param data     待加密数据
     * @param encoding 待加密数据编码
     * @return 加密后数据
     */
    public static String encryptRSAToHex(Key key, String data, String encoding) {
        try {
            return encryptRSAToHex(key, data.getBytes(encoding));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key  秘钥
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static String encryptRSAToHex(Key key, String data) {
        try {
            return encryptRSAToHex(key, data, ENCODING_UTF8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key  秘钥
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static String encryptRSAToBase64(Key key, byte[] data) {
        return encryptBASE64(encryptRSA(key, data));
    }

    /**
     * 加密
     *
     * @param key      秘钥
     * @param data     待加密数据
     * @param encoding 待加密数据编码
     * @return 加密后数据
     */
    public static String encryptRSAToBase64(Key key, String data, String encoding) {
        try {
            return encryptRSAToBase64(key, data.getBytes(encoding));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加密
     *
     * @param key  秘钥
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static String encryptRSAToBase64(Key key, String data) {
        try {
            return encryptRSAToBase64(key, data, ENCODING_UTF8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key  秘钥
     * @param data 待解密数据
     * @return 解密数据
     */
    public static byte[] decryptRSA(Key key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
            cipher.init(Cipher.DECRYPT_MODE, key);

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int splitLength = ((RSAKey) key).getModulus().bitLength() / 8;
            byte[][] arrays = splitBytes(data, splitLength);
            for (byte[] array : arrays) {
                byte[] cache = cipher.doFinal(array);
                out.write(cache, 0, cache.length);
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            return encryptedData;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key  秘钥
     * @param data 待解密数据
     * @return 解密数据
     */
    public static byte[] decryptRSAFromHex(Key key, String data) {
        try {
            return decryptRSA(key, hexToBytes(data));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key      秘钥
     * @param data     待解密数据
     * @param encoding 解密后数据编码
     * @return 解密数据
     */
    public static String decryptRSAFromHexToString(Key key, String data, String encoding) {
        try {
            return new String(decryptRSAFromHex(key, data), encoding);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key  秘钥
     * @param data 待解密数据
     * @return 解密数据
     */
    public static String decryptRSAFromHexToString(Key key, String data) {
        return decryptRSAFromHexToString(key, data, ENCODING_UTF8);
    }

    /**
     * 解密
     *
     * @param key  秘钥
     * @param data 待解密数据
     * @return 解密数据
     */
    public static byte[] decryptRSAFromBase64(Key key, String data) {
        try {
            return decryptRSA(key, decryptBASE64(data));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key      秘钥
     * @param data     待解密数据
     * @param encoding 解密后数据编码
     * @return 解密数据
     */
    public static String decryptRSAFromBase64ToString(Key key, String data, String encoding) {
        try {
            return new String(decryptRSAFromBase64(key, data), encoding);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     *
     * @param key  秘钥
     * @param data 待解密数据
     * @return 解密数据
     */
    public static String decryptRSAFromBase64ToString(Key key, String data) {
        return decryptRSAFromBase64ToString(key, data, ENCODING_UTF8);
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @return 签名值
     */
    public static byte[] signRSA(String signAlgorithms, PrivateKey privateKey, byte[] data) {
        try {
            Signature signature = Signature.getInstance(signAlgorithms);
            signature.initSign(privateKey);
            signature.update(data);
            return signature.sign();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @return 签名值
     */
    public static String signRSAToHex(String signAlgorithms, PrivateKey privateKey, byte[] data) {
        return bytesToHex(signRSA(signAlgorithms, privateKey, data));
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @param encoding       待签名数据编码
     * @return 签名值
     */
    public static String signRSAToHex(String signAlgorithms, PrivateKey privateKey, String data, String encoding) {
        try {
            return signRSAToHex(signAlgorithms, privateKey, data.getBytes(encoding));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @return 签名值
     */
    public static String signRSAToHex(String signAlgorithms, PrivateKey privateKey, String data) {
        return signRSAToHex(signAlgorithms, privateKey, data, ENCODING_UTF8);
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @return 签名值
     */
    public static String signRSAToBase64(String signAlgorithms, PrivateKey privateKey, byte[] data) {
        return encryptBASE64(signRSA(signAlgorithms, privateKey, data));
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @param encoding       待签名数据编码
     * @return 签名值
     */
    public static String signRSAToBase64(String signAlgorithms, PrivateKey privateKey, String data, String encoding) {
        try {
            return signRSAToBase64(signAlgorithms, privateKey, data.getBytes(encoding));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RSA签名
     *
     * @param signAlgorithms 签名算法
     * @param privateKey     私钥
     * @param data           待签名数据
     * @return 签名值
     */
    public static String signRSAToBase64(String signAlgorithms, PrivateKey privateKey, String data) {
        return signRSAToBase64(signAlgorithms, privateKey, data, ENCODING_UTF8);
    }

    /**
     * RSA验签名验证
     *
     * @param signAlgorithms 签名算法
     * @param publicKey      公钥
     * @param data           待签名数据
     * @param sign           签名值
     * @return 是否通过验证
     */
    public static boolean verifyRSA(String signAlgorithms, PublicKey publicKey, byte[] data, byte[] sign) {
        try {
            Signature signature = Signature.getInstance(signAlgorithms);
            signature.initVerify(publicKey);
            signature.update(data);
            return signature.verify(sign);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * RSA验签名验证
     *
     * @param signAlgorithms 签名算法
     * @param publicKey      公钥
     * @param data           待签名数据
     * @param signHex        十六进制签名值
     * @return 是否通过验证
     */
    public static boolean verifyRSAFromHex(String signAlgorithms, PublicKey publicKey, byte[] data, String signHex) {
        return verifyRSA(signAlgorithms, publicKey, data, hexToBytes(signHex));
    }

    /**
     * RSA验签名验证
     *
     * @param signAlgorithms 签名算法
     * @param publicKey      公钥
     * @param data           待签名数据
     * @param signBase64     base64签名值
     * @return 是否通过验证
     */
    public static boolean verifyRSAFromBase64(String signAlgorithms, PublicKey publicKey, byte[] data, String signBase64) {
        return verifyRSA(signAlgorithms, publicKey, data, decryptBASE64(signBase64));
    }

    /**
     * 按照指定长度对内容进行分段
     *
     * @param bytes       原文
     * @param splitLength 分段长度
     * @return 分段内容
     */
    private static byte[][] splitBytes(byte[] bytes, int splitLength) {
        int x; //商,数据拆分的组数,余数不为0时+1
        int y; //余数
        y = bytes.length % splitLength;
        if (y != 0) {
            x = bytes.length / splitLength + 1;
        } else {
            x = bytes.length / splitLength;
        }
        byte[][] arrays = new byte[x][];
        byte[] array;
        for (int i = 0; i < x; i++) {
            if (i == x - 1 && bytes.length % splitLength != 0) {
                array = new byte[bytes.length % splitLength];
                System.arraycopy(bytes, i * splitLength, array, 0, bytes.length % splitLength);
            } else {
                array = new byte[splitLength];
                System.arraycopy(bytes, i * splitLength, array, 0, splitLength);
            }
            arrays[i] = array;
        }
        return arrays;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy