非对称加密类(RSA)

package com.example.study.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class SecretUtil {
    public static final String CHARSET_UTF = "UTF-8";
    public static final String CHARSET_GBK = "GBK";

    // 设置公钥,私钥长度
    public static final int KEY_SIZE = 2048;

    public static final String PUBLIC_KEY_NAME = "publicKey";
    public static final String PRIVATE_KEY_NAME = "privateKey";

    // 定义加密算法,有DES、DESede(即3DES)、Blowfish
    public static final String ALGORITHM_3DES = "DESede";
    public static final String ALGORITHM_RSA = "RSA";
    public static final String SIGNATURE_ALGORITHM_SHA256 = "SHA256withRSA";

    // transformation的格式是“算法/工作模式/填充模式”
    public static final String TRANSFORMATION_ECB = "DESede/ECB/PKCS5Padding";
    public static final String TRANSFORMATION_CBC = "DESede/CBC/PKCS5Padding";

    // 默认加密密码
    public static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";

    /**
     * 3DES 加密
     *
     * @param key     密钥
     * @param content 加密内容
     * @return 密文
     */
    public static String des3Encrypt(String key, String content) {
        try {
            SecretKey secretKey = build3DesKey(key);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_ECB);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] res = cipher.doFinal(content.getBytes(CHARSET_UTF));
            //encodeBase64会对字符串3位一组自动补全,因而最后可能会出现 == 或者 =
            return new String(Base64.encodeBase64(res), CHARSET_UTF);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 3DES 加密
     *
     * @param content 明文
     * @return 密文
     */
    public static String des3Encrypt(String content) {
        return des3Encrypt(PASSWORD_CRYPT_KEY, content);
    }

    /**
     * 3DES 解密
     *
     * @param key     密钥
     * @param content 解密内容
     * @return 明文
     */
    public static String des3Decode(String key, String content) {
        try {
            SecretKey secretKey = build3DesKey(key);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_ECB);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] res = cipher.doFinal(Base64.decodeBase64(content.getBytes(CHARSET_UTF)));
            return new String(res, CHARSET_UTF);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 3DES 解密
     *
     * @param content 密文
     * @return 明文
     */
    public static String des3Decode(String content) {
        return des3Decode(PASSWORD_CRYPT_KEY, content);
    }

    /**
     * 根据字符串生成密钥字节数组
     *
     * @param keyStr 密钥字符串
     * @return 密钥
     * @throws Exception
     */
    public static SecretKey build3DesKey(String keyStr) throws Exception {
        byte[] key = new byte[24];    //声明一个24位的字节数组,默认里面都是0
        byte[] temp = keyStr.getBytes(CHARSET_UTF);    //将字符串转成字节数组
        /*
         * 执行数组拷贝
         * System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
         */
        if (key.length > temp.length) {
            //如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            //如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        //DESedeKeySpec会帮你生成24位秘钥,key可以是任意长度
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
        SecretKey secretKey = keyFactory.generateSecret(spec);
        return secretKey;
    }

    /**
     * 生成公、私钥
     *
     * @return map
     */
    public static Map<String, String> generateRsaKeys() {
        Map<String, String> keyPairMap = new HashMap<String, String>();
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_RSA);
            keyPairGenerator.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();

            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            //获取公、私钥值
            String publicKeyValue = Base64.encodeBase64String(publicKey.getEncoded());
            String privateKeyValue = Base64.encodeBase64String(privateKey.getEncoded());

            //存入
            keyPairMap.put(PUBLIC_KEY_NAME, publicKeyValue);
            keyPairMap.put(PRIVATE_KEY_NAME, privateKeyValue);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return keyPairMap;
    }

    /**
     * 解码 PublicKey
     *
     * @param key
     * @return
     */
    public static PublicKey getPublicKey(String key) {
        try {
            byte[] byteKey = Base64.decodeBase64(key);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            return keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解码 PrivateKey
     *
     * @param key
     * @return
     */
    public static PrivateKey getPrivateKey(String key) {
        try {
            byte[] byteKey = Base64.decodeBase64(key);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 签名
     *
     * @param key         私钥
     * @param requestData 请求参数
     * @return
     */
    public static String sign(String key, String requestData) {
        String signature = null;
        try {
            PrivateKey privateKey = getPrivateKey(key);
            Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM_SHA256);
            Sign.initSign(privateKey);
            Sign.update(requestData.getBytes());
            signature = Base64.encodeBase64String(Sign.sign());
            System.out.println("===签名结果:" + signature);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return signature;
    }

    /**
     * 验签
     *
     * @param key         公钥
     * @param requestData 请求参数
     * @param signature   签名
     * @return
     */
    public static boolean verifySign(String key, String requestData, String signature) {
        boolean verifySignRes = false;
        try {
            PublicKey publicKey = getPublicKey(key);
            Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM_SHA256);
            verifySign.initVerify(publicKey);
            verifySign.update(requestData.getBytes());
            verifySignRes = verifySign.verify(Base64.decodeBase64(signature));
            System.out.println("===验签结果:" + verifySignRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return verifySignRes;
    }

    /**
     * 构建签名数据, 将 Map 转成 key1=value1&key2=value2...(按照字段名的ASCII 码从小到大排序,即字典序)
     * @param params 请求参数
     * @return
     */
    public static String buildSignData(Map<String,Object> params){
        StringBuilder sb = new StringBuilder();
        // 将参数以参数名的字典升序排序
        Map<String, Object> sortParams = new TreeMap<>(params);
        // 遍历排序的字典,并拼接"key=value"格式
        for (Map.Entry<String, Object> entry : sortParams.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        if (!sortParams.isEmpty()) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String key = "123456";
        String msg = "3DES加密解密案例";
        System.out.println("【加密前】:" + msg);

        //加密
        String cipherText = SecretUtil.des3Encrypt(key, msg);
        System.out.println("【加密后】:" + cipherText);

        //解密
        String msgText = SecretUtil.des3Decode(key, cipherText);
        System.out.println("【解密后】:" + msgText);

        //签名 验签
        Map<String, String> keyPairMap = generateRsaKeys();
        System.out.println("生成公、私钥测试:"+keyPairMap);

        String publicKey = keyPairMap.get(PUBLIC_KEY_NAME);
        String privateKey = keyPairMap.get(PRIVATE_KEY_NAME);

        System.out.println("===开始RSA公、私钥测试===");
        String str = "alpha=001&beta=002&gamma=003";
        String sign = sign(privateKey, str);

        verifySign(publicKey, str, sign);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值