RSA非对称性加密

RSA非对称性加密

RSA工具类

package com.example.base.utils;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Other
 */
public class RsaUtil {

    private static final Logger logger = LoggerFactory.getLogger(RsaUtil.class);
    /** 算法常量 */
    private static final String ALGORITHMSTR = "RSA";
    /** 编码格式 */
    private static final String DEFAULT_CHAR_SET = "UTF-8";
    /** 获取公钥的key */
    private static final String PUBLIC_KEY = "RSAPublicKey";
    /** 获取私钥的key */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 生成公钥私钥
     */
    public static Map<String, String> genKeyPair(){
        //用于封装随机产生的公钥与私钥
        Map<String, String> keyMap = new HashMap<>(2);
        try {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHMSTR);
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGen.initialize(1024, new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 得到公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 得到私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

            // 得到公钥字符串
            String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()), DEFAULT_CHAR_SET);
            // 得到私钥字符串
            String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())), DEFAULT_CHAR_SET);
            // 将公钥和私钥保存到Map
            keyMap.put(PUBLIC_KEY, publicKeyString);
            keyMap.put(PRIVATE_KEY, privateKeyString);
        }catch (Exception e){
            logger.error("RsaUtil | method=genKeyPair() is error, error_msg:{}, error:{}",e.getMessage(),e);
        }
        return keyMap;
    }

    /**
     * 获取公钥
     */
    public static String getPublicKey(Map<String, String> keyMap) {
        String key = keyMap.get(PUBLIC_KEY);
        return (null != key && !"".equals(key))  ? key : null;
    }

    /**
     * 获取私钥
     */
    public static String getPrivateKey(Map<String, String> keyMap) {
        String key = keyMap.get(PRIVATE_KEY);
        return (null != key && !"".equals(key)) ? key : null;
    }

    /**
     * 加密
     * @param content 原文
     * @param publicKey 公钥
     * @return 加密数据
     * @throws Exception
     */
    public static String encrypt(String content, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        RSAPublicKey rsaPublicKey = (RSAPublicKey) KeyFactory.getInstance(ALGORITHMSTR).generatePublic(new X509EncodedKeySpec(keyBytes));

        //RSA加密
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);

        int offSet = 0;
        int offlimt = 117;
        byte[] bytes = content.getBytes(DEFAULT_CHAR_SET);
        byte[] outBytes = splitBytes(cipher, offSet, offlimt, bytes);
        return Base64.encodeBase64String(outBytes);
    }

    /**
     * 解密
     * @param encrypt 已加密数据
     * @param privateKey 私钥
     * @return 原文
     * @throws Exception
     */
    public static String decrypt(String encrypt, String privateKey) throws Exception {

        //64位解码加密后的字符串
        byte[] bytes = Base64.decodeBase64(encrypt.getBytes(DEFAULT_CHAR_SET));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGORITHMSTR).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        //RSA最大解密密文大小
        int offSet = 0;
        int offlimt = 128;
        byte[] outBytes = splitBytes(cipher, offSet, offlimt, bytes);
        return new String(outBytes, DEFAULT_CHAR_SET);
    }

    /**
     * 分割执行加解密
     */
    private static byte[] splitBytes(Cipher cipher, int offSet, int offlimt, byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int length = bytes.length;
        while (length - offSet > 0){
            byte[] cache;
            if(length - offSet > offlimt){
                cache = cipher.doFinal(bytes, offSet, offlimt);
            }else{
                cache = cipher.doFinal(bytes, offSet, length - offSet);
            }
            out.write(cache, 0, cache.length);
            offSet += offlimt;
        }
        byte[] outBytes = out.toByteArray();
        out.close();
        return outBytes;
    }

    /**
     * 私钥生成签名
     * @param content 内容
     * @param privateKey 私钥
     * @return 生成的签名
     * @throws Exception
     */
    public static String sign(String content, String privateKey) throws Exception {
        //签名算法
        String signatureAlgorithm = "MD5withRSA";
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHMSTR);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(signatureAlgorithm);
        signature.initSign(privateK);
        signature.update(content.getBytes(DEFAULT_CHAR_SET));
        return Base64.encodeBase64String(signature.sign());
    }

    /**
     * 公钥验证签名
     * @param content
     * @param publicKey
     * @param sign
     * @return
     * @throws Exception
     */
    public static boolean verify(String content, String publicKey, String sign) throws Exception {
        //签名算法
        String signatureAlgorithm = "MD5withRSA";
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHMSTR);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(signatureAlgorithm);
        signature.initVerify(publicK);
        signature.update(content.getBytes(DEFAULT_CHAR_SET));
        return signature.verify(Base64.decodeBase64(sign));
    }

    public static void main(String[] args) throws Exception {
        String content = "这是一个测试方法";

        Map<String, String> keyMap = genKeyPair();
        String publicKey = getPublicKey(keyMap);
        System.out.println("公钥:" + publicKey);
        String privateKey = getPrivateKey(keyMap);
        System.out.println("私钥:" + privateKey);

        String encrypt = encrypt(content, publicKey);
        System.out.println("加密后:" + encrypt);
        String decrypt = decrypt(encrypt, privateKey);
        System.out.println("解密后:" + decrypt);

        String sign = sign(content, privateKey);
        System.out.println("签名:" + sign);
        System.out.println("验证:" + verify(content, publicKey, sign));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值