Java实现RSA加密解密工具类

1、Maven引用Base64依赖

<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.15</version>
</dependency>

2、工具类编写,直接复制就可以。实现了两种加密解密工具方法,该方法会抛出运行时异常,可以根据自己的需求自定义修改。

package com.tancire.rsa;

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

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
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;

public class RsaUtils {

    /**
     * 加密方式
     */
    public static final String CIPHER_KEY = "RSA";

    /**
     * 默认
     */
    public static final int DEFAULT_KEY_SIZE = 2048;

    /**
     * 加密
     */
    public static final int ENCRYPT = 1;

    /**
     * 解密
     */
    public static final int DECRYPT = 2;

    /**
     * 公钥键值
     */
    public static final String PUBLIC_KEY = "public";

    /**
     * 私钥键值
     */
    public static final String PRIVATE_KEY = "private";

    /**
     * 生成RSA密钥对
     *
     * @return
     */
    public static Map<String, String> generateRsaPair() {
        return generateRsaPair(DEFAULT_KEY_SIZE);
    }


    /**
     * 生成RSA密钥对
     *
     * @param keySize
     * @return
     */
    public static Map<String, String> generateRsaPair(int keySize) {
        Map<String, String> resPair = new HashMap<>();
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(CIPHER_KEY);
            keyPairGenerator.initialize(keySize);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            resPair.put(PUBLIC_KEY, Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            resPair.put(PRIVATE_KEY, Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
        } catch (Exception e) {
            throw new RuntimeException("创建密钥失败");
        }
        return resPair;
    }


    /**
     * 公钥
     * 加密/解密
     *
     * @return
     */
    public static String pubRsa(String letter, String publicKey, int mode) {
        try {
            byte[] bytes = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
            KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
            PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(CIPHER_KEY);
            cipher.init(mode, key);
            return codeHandle(letter, cipher, mode);
        } catch (Exception e) {
            if (Cipher.ENCRYPT_MODE == mode) {
                throw new RuntimeException("加密数据失败");
            } else {
                throw new RuntimeException("解密数据失败");
            }
        }
    }

    /**
     * 公钥
     * 加密/解密
     *
     * @return
     */
    public static String priRsa(String letter, String privateKey, int mode) {
        try {
            byte[] bytes = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
            KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
            PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(CIPHER_KEY);
            cipher.init(mode, key);
            return codeHandle(letter, cipher, mode);
        } catch (Exception e) {
            if (Cipher.ENCRYPT_MODE == mode) {
                throw new RuntimeException("加密数据失败");
            } else {
                throw new RuntimeException("解密数据失败");
            }
        }
    }

    /**
     * 加密
     * 公钥加密不需要传私钥,私钥加密不需要传公钥
     *
     * @return
     */
    public static String rsaEncrypt(String publicKey, String privateKey, String letter) {
        try {
            if (null != publicKey && null == privateKey) {
                byte[] bytes = Base64.decodeBase64(publicKey);
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
                KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
                PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
                Cipher cipher = Cipher.getInstance(CIPHER_KEY);
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] res = cipher.doFinal(letter.getBytes(StandardCharsets.UTF_8));
                return Base64.encodeBase64String(res);
            } else if (null == publicKey && null != privateKey) {
                byte[] bytes = Base64.decodeBase64(privateKey);
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
                KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
                PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
                Cipher cipher = Cipher.getInstance(CIPHER_KEY);
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] res = cipher.doFinal(letter.getBytes(StandardCharsets.UTF_8));
                return Base64.encodeBase64String(res);
            } else {
                throw new RuntimeException("请正确传入公钥和私钥");
            }
        } catch (Exception e) {
            throw new RuntimeException("加密数据失败");
        }
    }

    /**
     * 解密
     *
     * @return
     */
    public static String rsaDecrypt(String publicKey, String privateKey, String letter) {
        try {
            if (null != publicKey && null == privateKey) {
                byte[] bytes = Base64.decodeBase64(publicKey);
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
                KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
                PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
                Cipher cipher = Cipher.getInstance(CIPHER_KEY);
                cipher.init(Cipher.DECRYPT_MODE, key);
                byte[] letterBytes = Base64.decodeBase64(letter);
                byte[] res = cipher.doFinal(letterBytes);
                return new String(res, StandardCharsets.UTF_8);
            } else if (null == publicKey && null != privateKey) {
                byte[] bytes = Base64.decodeBase64(privateKey);
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
                KeyFactory keyFactory = KeyFactory.getInstance(CIPHER_KEY);
                PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
                Cipher cipher = Cipher.getInstance(CIPHER_KEY);
                cipher.init(Cipher.DECRYPT_MODE, key);
                byte[] letterBytes = Base64.decodeBase64(letter);
                byte[] res = cipher.doFinal(letterBytes);
                return new String(res, StandardCharsets.UTF_8);
            } else {
                throw new RuntimeException("请正确传入公钥和私钥");
            }
        } catch (Exception e) {
            throw new RuntimeException("解密数据失败");
        }
    }

    private static String codeHandle(String letter, Cipher cipher, int mode) {
        try {
            if (Cipher.ENCRYPT_MODE == mode) {
                // 加密
                byte[] res = cipher.doFinal(letter.getBytes(StandardCharsets.UTF_8));
                return Base64.encodeBase64String(res);
            } else if (Cipher.DECRYPT_MODE == mode) {
                // 解密
                byte[] letterBytes = Base64.decodeBase64(letter);
                byte[] res = cipher.doFinal(letterBytes);
                return new String(res, StandardCharsets.UTF_8);
            } else {
                throw new RuntimeException("不支持当前模式");
            }
        } catch (Exception e) {
            throw new RuntimeException("不支持当前模式");
        }
    }

}


3、测试工具类,目前此代码能在JDK1.8环境下正常运行。

package com.tancire.rsa;

import java.util.Map;

import static java.lang.System.out;

/**
 * RSA 加密工具类
 * 已经封装好,可以直接使用
 * 目前在jdk1.8环境运行正常
 *
 * @version 1.0
 * @date 2024-04-09 20:00:00
 */
public class TancireRsa {


    public static void main(String[] args) {
        // jdkRsa();

        Map<String, String> pairMap = RsaUtils.generateRsaPair();
        String publicKey = pairMap.get(RsaUtils.PUBLIC_KEY);
        String privateKey = pairMap.get(RsaUtils.PRIVATE_KEY);

        out.println("公钥:" + publicKey);
        out.println("私钥:" + privateKey);
        // 加密数据
        String letter = "关注‘天晴软件’公众号,获取开源软件最新消息!";
        String a = RsaUtils.rsaEncrypt(publicKey, null, letter);
        out.println("公钥加密密文:" + a);
        String b = RsaUtils.rsaDecrypt(null, privateKey, a);
        out.println("私钥解密:" + b);
        // 反向
        String c = RsaUtils.rsaEncrypt(null, privateKey, letter);
        out.println("私钥加密密文:" + c);
        String d = RsaUtils.rsaDecrypt(publicKey, null, c);
        out.println("公钥解密:" + d);

        // 公钥加密
        String aa = RsaUtils.pubRsa(letter, publicKey, RsaUtils.ENCRYPT);
        out.println("公钥加密密文:" + aa);
        String bb = RsaUtils.priRsa(aa, privateKey, RsaUtils.DECRYPT);
        out.println("私钥解密:" + bb);

        String cc = RsaUtils.priRsa(letter, privateKey, RsaUtils.ENCRYPT);
        out.println("私钥加密密文:" + cc);
        String dd = RsaUtils.pubRsa(cc, publicKey, RsaUtils.DECRYPT);
        out.println("私钥解密:" + dd);

    }
}

posted @ 2024-04-11 09:04  hakood  阅读(377)  评论(0)    收藏  举报