天天看点

Java实现RSA加解密(代码)

本博客的代码经过自己慢慢调试,全部都成功运行
 特别注意的是:
  • Base64的包要这个,import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
  • key的长度是根据密钥的长度决定,private static final int KEY_SIZE = 1024;
  • 在线生成密钥对的网址:http://web.chacuo.net/netrsakeypair,可以自己生成密钥对来验证
  • php格式密钥转换为Java格式的密钥:public static String getCerToPublicKey() throws CertificateException
package wofang.common.utils;


import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * @author 林高禄
 * @create 2020-05-15-15:09
 */
public class RsaUtils {

    /** *//**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 填充方式
     */
    public static final String CIPHERALGORITHM = "RSA/ECB/PKCS1Padding";

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * php公钥的key
     */
    public static final String PHP_PUBLIC_KEY = "-----BEGIN CERTIFICATE-----\n" +
            "MIICjTCCAfYCCQD0L/1fW/xYMjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC\n" +
            "Q04xDzANBgNVBAgMBkhhaU5hbjEPMA0GA1UEBwwGSGFpS291MQ8wDQYDVQQKDAZX\n" +
            "b0ZhbmcxDzANBgNVBAsMBldvRmFuZzEZMBcGA1UEAwwQd3hhcGkud29mYW5nLmNv\n" +
            "bTEcMBoGCSqGSIb3DQEJARYNd29mYW5nQHFxLmNvbTAeFw0xODA1MjIwNjQ2NTJa\n" +
            "Fw0yODA1MTkwNjQ2NTJaMIGKMQswCQYDVQQGEwJDTjEPMA0GA1UECAwGSGFpTmFu\n" +
            "MQ8wDQYDVQQHDAZIYWlLb3UxDzANBgNVBAoMBldvRmFuZzEPMA0GA1UECwwGV29G\n" +
            "YW5nMRkwFwYDVQQDDBB3eGFwaS53b2ZhbmcuY29tMRwwGgYJKoZIhvcNAQkBFg13\n" +
            "b2ZhbmdAcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo5zysftrH\n" +
            "mlfuZ3Fokzha1w+rmZc3MIgWL+3Z7URCasSr3TtSaaTYnl91VCfTF78rEhdZG7h6\n" +
            "8kgzovc5alMRmPBtEe9Enr9G+XPN6RCu6Y1nFRepIIscXghBpISj1Cofe6SUGgHY\n" +
            "5S9THNZsXSHxsvNLcPcOFEZtBKcSz9FXlwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB\n" +
            "AHEIGEVJSQmLH3qPu4/8qHVYF3iB3sFDrnU+aYm0L0b/y0TeTjtztpAerMTK3LLA\n" +
            "RBVxjwSQzdIf9EDihYl/VrZSlxjkvoE2k1dRxNg1dBZLraZPle6cgEq+l2nh6FD9\n" +
            "Xzx8udLo2sr5wbGsldmyTZGcpjGSOOecGaGh6Xvh0CEC\n" +
            "-----END CERTIFICATE-----";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 长度
     */
    private static final int KEY_SIZE = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;

    /**
     * 用于封装随机产生的公钥与私钥
     */
    private static Map<String, Key> keyMap = new HashMap<String, Key>();

    /**
     * 生成密钥对(公钥和私钥)
     * @throws          Exception       异常
     */
    public static void genKeyPair() throws Exception {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 得到公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
    }

    /**
     * 密钥转换,去除其他格式,换行符等
     * @param privateKey    私钥
     * @return              String
     */
    public static String keyTransformation(String privateKey,String begin,String end){
        return privateKey.replace(begin, "")
                 .replace(end, "")
                .replace("\r\n", "")
                .replace("\r", "")
                .replace("\n", "") ;
    }


    /**
     * 获取私钥
     * @return String
     */
    public static String getPrivateKey(){
        Key key = keyMap.get(PRIVATE_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * 获取公钥
     * @return  String
     */
    public static String getPublicKey(){
        Key key = keyMap.get(PUBLIC_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * php格式密钥转换为Java格式的密钥
     * BEGIN CERTIFICATE格式解析密钥
     * @Return: java.security.PublicKey
     */
    public static String getCerToPublicKey() throws CertificateException {
        //FileInputStream file = new FileInputStream("D://publicKey.cer");
        String phpPublicKey = keyTransformation(RsaUtils.PHP_PUBLIC_KEY,"-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
        byte[] phpKeyBytes = Base64.decode(phpPublicKey);
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        InputStream in = new ByteArrayInputStream(phpKeyBytes);
        X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
        PublicKey publicKey = certificate.getPublicKey();
       /* CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(file);
        PublicKey publicKey = certificate.getPublicKey();*/
        String strKey = "-----BEGIN PUBLIC KEY-----\n"
                + Base64.encode(publicKey.getEncoded())
                + "\n-----END PUBLIC KEY-----";
        return strKey;
    }

    /**
     * 用私钥对信息生成数字签名
     * @param data              已加密数据
     * @param privateKey        私钥(BASE64编码)
     * @return                  String
     * @throws Exception       异常
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return Base64.encode(signature.sign());
    }

    /**
     * 校验数字签名
     * @param data                  已加密数据
     * @param publicKey             公钥(BASE64编码)
     * @param sign                  数字签名
     * @return                      boolean
     * @throws Exception           异常
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);
        return signature.verify(Base64.decode(sign));
    }

    /**
     * 分片私钥解密
     * @param encryptedData         已加密数据
     * @param privateKey            私钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey, String cipherAlgorithm)
            throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * 分片公钥解密
     * @param encryptedData         已加密数据
     * @param publicKey             公钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey,String cipherAlgorithm)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * 分片公钥加密
     * @param data                  源数据
     * @param publicKey             公钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey,String cipherAlgorithm)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream(MAX_ENCRYPT_BLOCK);
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * 分片私钥加密
     * @param data                  源数据
     * @param privateKey            私钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] encryptByPrivateKey(byte[] data, String privateKey,String cipherAlgorithm)
            throws Exception {

        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * RSA全部公钥加密
     * @param str                   加密字符串
     * @param publicKey             公钥
     * @param cipherAlgorithm       填充方式
     * @return                      密文
     * @throws Exception           加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey,String cipherAlgorithm) throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
        //RSA加密
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance("RSA");
        }
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encode(cipher.doFinal(str.getBytes("UTF-8")));
    }

    /**
     * RSA全部私钥解密
     *
     * @param str                   加密字符串
     * @param privateKey            私钥
     * @param cipherAlgorithm       填充方式
     * @return                      明文
     * @throws Exception           解密过程中的异常信息
     */
    public static String decrypt(String str, String privateKey,String cipherAlgorithm) throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decode(str);
        byte[] keyBytes = Base64.decode(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
        //RSA解密
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance("RSA");
        }
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    public static void main(String[] args) {
        Map<String,Object> parameters = new LinkedHashMap<>();
        parameters.put("t","10086");
        parameters.put("b",10533L);
        // 随机字符串
        String randomString = RandomStringUtils.randomAlphanumeric(10);
        parameters.put("nonceStr",randomString);
        String sign = MD5Utils.createSign("UTF-8", parameters, "&key=", null, true);
        System.out.println("sign=:"+sign);
        parameters.put("sign",sign);
        // map转为Json字符串
        String mapString = JSON.toJSONString(parameters);
        if(StringUtils.isBlank(mapString)){
            return;
        }
        try {
            RsaUtils.genKeyPair();
            System.out.println(mapString);
            String messageEn = encrypt(mapString, RsaUtils.getPublicKey(),null);
            System.out.println("我的key全部加密密文1:"+messageEn);
            String decrypt = RsaUtils.decrypt(messageEn, RsaUtils.getPrivateKey(),null);
            System.out.println("我的key全部解密原文1:"+decrypt);

            byte[] bytes = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), RsaUtils.getPublicKey(),null);;
            String ws  = Base64.encode(bytes);
            System.out.println("我的key分片加密密文1:"+ws);
            byte[] decode = Base64.decode(ws);
            byte[] bytes1 = RsaUtils.decryptByPrivateKey(decode, RsaUtils.getPrivateKey(),null);
            System.out.println("我的key分片解密原文1:"+new String(bytes1));

            String cerToPublicKey = getCerToPublicKey();
            System.out.println("转换后的key:"+ cerToPublicKey);
            byte[] bytes2 = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), cerToPublicKey,RsaUtils.CIPHERALGORITHM);
            String s2 = Base64.encode(bytes2);
            System.out.println("他的key分片加密密文1:"+s2);
            s2 = s2.replace("+", "\\\\u002b");
            System.out.println("他的key分片加密密文1:"+s2);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
           
package wofang.common.utils;


import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * @author 林高禄
 * @create 2020-05-15-15:09
 */
public class RsaUtils {

    /** *//**
     * 加密算法RSA
     */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 填充方式
     */
    public static final String CIPHERALGORITHM = "RSA/ECB/PKCS1Padding";

    /**
     * 签名算法
     */
    private static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * php公钥的key
     */
    private static final String PHP_PUBLIC_KEY = "-----BEGIN CERTIFICATE-----\n" +
            "MIICjTCCAfYCCQD0L/1fW/xYMjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC\n" +
            "Q04xDzANBgNVBAgMBkhhaU5hbjEPMA0GA1UEBwwGSGFpS291MQ8wDQYDVQQKDAZX\n" +
            "b0ZhbmcxDzANBgNVBAsMBldvRmFuZzEZMBcGA1UEAwwQd3hhcGkud29mYW5nLmNv\n" +
            "bTEcMBoGCSqGSIb3DQEJARYNd29mYW5nQHFxLmNvbTAeFw0xODA1MjIwNjQ2NTJa\n" +
            "Fw0yODA1MTkwNjQ2NTJaMIGKMQswCQYDVQQGEwJDTjEPMA0GA1UECAwGSGFpTmFu\n" +
            "MQ8wDQYDVQQHDAZIYWlLb3UxDzANBgNVBAoMBldvRmFuZzEPMA0GA1UECwwGV29G\n" +
            "YW5nMRkwFwYDVQQDDBB3eGFwaS53b2ZhbmcuY29tMRwwGgYJKoZIhvcNAQkBFg13\n" +
            "b2ZhbmdAcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo5zysftrH\n" +
            "mlfuZ3Fokzha1w+rmZc3MIgWL+3Z7URCasSr3TtSaaTYnl91VCfTF78rEhdZG7h6\n" +
            "8kgzovc5alMRmPBtEe9Enr9G+XPN6RCu6Y1nFRepIIscXghBpISj1Cofe6SUGgHY\n" +
            "5S9THNZsXSHxsvNLcPcOFEZtBKcSz9FXlwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB\n" +
            "AHEIGEVJSQmLH3qPu4/8qHVYF3iB3sFDrnU+aYm0L0b/y0TeTjtztpAerMTK3LLA\n" +
            "RBVxjwSQzdIf9EDihYl/VrZSlxjkvoE2k1dRxNg1dBZLraZPle6cgEq+l2nh6FD9\n" +
            "Xzx8udLo2sr5wbGsldmyTZGcpjGSOOecGaGh6Xvh0CEC\n" +
            "-----END CERTIFICATE-----";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 长度
     */
    private static final int KEY_SIZE = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;

    /**
     * 用于封装随机产生的公钥与私钥
     */
    private static Map<String, Key> keyMap = new HashMap<String, Key>();

    /**
     * 生成密钥对(公钥和私钥)
     * @throws          Exception       异常
     */
    public static void genKeyPair() throws Exception {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 得到公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
    }

    /**
     * 密钥转换,去除其他格式,换行符等
     * @param privateKey    私钥
     * @return              String
     */
    public static String keyTransformation(String privateKey,String begin,String end){
        return privateKey.replace(begin, "")
                 .replace(end, "")
                .replace("\r\n", "")
                .replace("\r", "")
                .replace("\n", "") ;
    }


    /**
     * 获取私钥
     * @return String
     */
    public static String getPrivateKey(){
        Key key = keyMap.get(PRIVATE_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * 获取公钥
     * @return  String
     */
    public static String getPublicKey(){
        Key key = keyMap.get(PUBLIC_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * php格式密钥转换为Java格式的密钥
     * BEGIN CERTIFICATE格式解析密钥
     * @Return: java.security.PublicKey
     */
    public static String getCerToPublicKey() throws CertificateException {
        //FileInputStream file = new FileInputStream("D://publicKey.cer");
        String phpPublicKey = keyTransformation(RsaUtils.PHP_PUBLIC_KEY,"-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
        byte[] phpKeyBytes = Base64.decode(phpPublicKey);
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        InputStream in = new ByteArrayInputStream(phpKeyBytes);
        X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
        PublicKey publicKey = certificate.getPublicKey();
       /* CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(file);
        PublicKey publicKey = certificate.getPublicKey();*/
        String strKey = "-----BEGIN PUBLIC KEY-----\n"
                + Base64.encode(publicKey.getEncoded())
                + "\n-----END PUBLIC KEY-----";
        return strKey;
    }

    /**
     * 用私钥对信息生成数字签名
     * @param data              已加密数据
     * @param privateKey        私钥(BASE64编码)
     * @return                  String
     * @throws Exception       异常
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return Base64.encode(signature.sign());
    }

    /**
     * 校验数字签名
     * @param data                  已加密数据
     * @param publicKey             公钥(BASE64编码)
     * @param sign                  数字签名
     * @return                      boolean
     * @throws Exception           异常
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);
        return signature.verify(Base64.decode(sign));
    }

    /**
     * 分片私钥解密
     * @param encryptedData         已加密数据
     * @param privateKey            私钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey, String cipherAlgorithm)
            throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return encryptAndDecrypt(encryptedData,keyFactory,priKey,Cipher.DECRYPT_MODE,MAX_DECRYPT_BLOCK,cipherAlgorithm);
    }

    /**
     * 分片公钥解密
     * @param encryptedData         已加密数据
     * @param publicKey             公钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey,String cipherAlgorithm)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key pubKey = keyFactory.generatePublic(x509KeySpec);
        return encryptAndDecrypt(encryptedData,keyFactory,pubKey,Cipher.DECRYPT_MODE,MAX_DECRYPT_BLOCK,cipherAlgorithm);
    }

    /**
     * 分片公钥加密
     * @param data                  源数据
     * @param publicKey             公钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey,String cipherAlgorithm)
            throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key pubKey = keyFactory.generatePublic(x509KeySpec);
        return encryptAndDecrypt(data,keyFactory,pubKey,Cipher.ENCRYPT_MODE,MAX_ENCRYPT_BLOCK,cipherAlgorithm);
    }

    /**
     * 分片私钥加密
     * @param data                  源数据
     * @param privateKey            私钥(BASE64编码)
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    public static byte[] encryptByPrivateKey(byte[] data, String privateKey,String cipherAlgorithm)
            throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return encryptAndDecrypt(data,keyFactory,priKey,Cipher.ENCRYPT_MODE,MAX_ENCRYPT_BLOCK,cipherAlgorithm);
    }

    /**
     *
     * @param data                  加密或解密数据
     * @param keyFactory            keyFactory
     * @param key                   私钥或者公钥
     * @param cipherMode            模式,Cipher.ENCRYPT_MODE-加密,Cipher.DECRYPT_MODE-解密
     * @param maxBlock              最大加解密明文大小
     * @param cipherAlgorithm       填充方式
     * @return                      byte[]
     * @throws Exception           异常
     */
    private static byte[]  encryptAndDecrypt(byte[] data, KeyFactory keyFactory,Key key,int cipherMode,int maxBlock,String cipherAlgorithm) throws Exception{
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        }
        cipher.init(cipherMode, key);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > maxBlock) {
                cache = cipher.doFinal(data, offSet, maxBlock);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * maxBlock;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }
    /**
     * RSA全部公钥加密
     * @param str                   加密字符串
     * @param publicKey             公钥
     * @param cipherAlgorithm       填充方式
     * @return                      密文
     * @throws Exception           加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey,String cipherAlgorithm) throws Exception {
        publicKey = keyTransformation(publicKey,"-----BEGIN PUBLIC KEY-----","-----END PUBLIC KEY-----");
        byte[] keyBytes = Base64.decode(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
        //RSA加密
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance("RSA");
        }
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encode(cipher.doFinal(str.getBytes("UTF-8")));
    }

    /**
     * RSA全部私钥解密
     *
     * @param str                   加密字符串
     * @param privateKey            私钥
     * @param cipherAlgorithm       填充方式
     * @return                      明文
     * @throws Exception           解密过程中的异常信息
     */
    public static String decrypt(String str, String privateKey,String cipherAlgorithm) throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decode(str);
        byte[] keyBytes = Base64.decode(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
        //RSA解密
        Cipher cipher;
        if(StringUtil.isNotBlank(cipherAlgorithm)){
            cipher = Cipher.getInstance(cipherAlgorithm);
        }else{
            cipher = Cipher.getInstance("RSA");
        }
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    public static void main(String[] args) {
        Map<String,Object> parameters = new LinkedHashMap<>();
        parameters.put("t","10086");
        parameters.put("b",10533L);
        // 随机字符串
        String randomString = RandomStringUtils.randomAlphanumeric(10);
        parameters.put("nonceStr",randomString);
        String sign = MD5Utils.createSign("UTF-8", parameters, "&key=", null, true);
        System.out.println("sign=:"+sign);
        parameters.put("sign",sign);
        // map转为Json字符串
        String mapString = JSON.toJSONString(parameters);
        if(StringUtils.isBlank(mapString)){
            return;
        }
        try {
            RsaUtils.genKeyPair();
            System.out.println(mapString);
            String messageEn = encrypt(mapString, RsaUtils.getPublicKey(),null);
            System.out.println("我的key全部加密密文1:"+messageEn);
            String decrypt = RsaUtils.decrypt(messageEn, RsaUtils.getPrivateKey(),null);
            System.out.println("我的key全部解密原文1:"+decrypt);

            byte[] bytes = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), RsaUtils.getPublicKey(),null);;
            String ws  = Base64.encode(bytes);
            System.out.println("我的key分片加密密文1:"+ws);
            byte[] decode = Base64.decode(ws);
            byte[] bytes1 = RsaUtils.decryptByPrivateKey(decode, RsaUtils.getPrivateKey(),null);
            System.out.println("我的key分片解密原文1:"+new String(bytes1));

            String cerToPublicKey = getCerToPublicKey();
            System.out.println("转换后的key:"+ cerToPublicKey);
            byte[] bytes2 = RsaUtils.encryptByPublicKey(mapString.getBytes("UTF-8"), cerToPublicKey,RsaUtils.CIPHERALGORITHM);
            String s2 = Base64.encode(bytes2);
            System.out.println("他的key分片加密密文1:"+s2);
            s2 = s2.replace("+", "\\\\u002b");
            System.out.println("他的key分片加密密文1:"+s2);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}