JAVA中的RSA加密/解密/签名/验签操作

背景

在对接三方接口或实现开放平台操作时需要对接口提交参数通过RSA公钥进行加密,在获取到请求数据后需要使用RSA私钥对数据进行解密操作。

RSA生成工具

支付宝的RSA生成工具

几种方式

1.自定义RsaUtil工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加解密工具
 *
 * @author sdevil507
 * created on 2021/5/27
 */
@Slf4j
public class RsaUtil {

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

    /**
     * 类型
     */
    public static final String RSA_TYPE = "RSA/ECB/PKCS1Padding";

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

    /**
     * 获取转换后的公钥
     *
     * @param publicKey 公钥字符串
     * @return 转换后的公钥
     */
    private static PublicKey getPublicKey(String publicKey) {
        try {
            byte[] byteKey = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            return keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取转换后的私钥
     *
     * @param privateKey 私钥字符串
     * @return 转换后的私钥
     */
    private static PrivateKey getPrivateKey(String privateKey) {
        try {
            byte[] byteKey = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 私钥签名
     *
     * @param privateKey 私钥
     * @param plainText  明文
     * @return 签名字符串
     */
    public static String sign(String privateKey, String plainText) {
        String signStr = null;
        byte[] signeBytes;
        try {
            log.info("签名前明文:{}", plainText);
            PrivateKey key = getPrivateKey(privateKey);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(key);
            signature.update(plainText.getBytes());
            signeBytes = signature.sign();
            signStr = Base64.encodeBase64String(signeBytes);
            log.info("签名后密文:{}", signStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signStr;
    }

    /**
     * 公钥验签
     *
     * @param plainText 待验签明文
     * @param signStr   签名密文
     * @return true/false
     */
    public static boolean verifySign(String publicKey, String plainText, String signStr) {
        boolean verifySignSuccess = false;
        try {
            PublicKey key = getPublicKey(publicKey);
            Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
            verifySign.initVerify(key);
            verifySign.update(plainText.getBytes());
            verifySignSuccess = verifySign.verify(Base64.decodeBase64(signStr));
            log.info("公钥验签结果:{}", verifySignSuccess);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return verifySignSuccess;
    }

    /**
     * 明文加密
     *
     * @param publicKey 公钥
     * @param plainText 明文
     * @return 密文
     */
    public static String encrypt(String publicKey, String plainText) {
        String encryptedBase64 = "";
        try {
            Key key = getPublicKey(publicKey);
            final Cipher cipher = Cipher.getInstance(RSA_TYPE);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 转换
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            encryptedBase64 = Base64.encodeBase64String(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedBase64;
    }

    /**
     * 密文解密
     *
     * @param privateKey      秘钥
     * @param encryptedBase64 密文
     * @return 明文
     */
    public static String decrypt(String privateKey, String encryptedBase64) {
        String decryptedString = "";
        try {
            Key key = getPrivateKey(privateKey);
            final Cipher cipher = Cipher.getInstance(RSA_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encryptedBytes = Base64.decodeBase64(encryptedBase64);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            decryptedString = new String(decryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptedString;
    }
}

2.使用hutool工具类中的RSA工具类

引入hutool类库

<dependency>
    <groupId>com.xiaoleilu</groupId>
    <artifactId>hutool-all</artifactId>
    <version>x.x.x</version>
</dependency>

测试代码

    @Test
    public void hutoolRsa() {
        // 公钥
        String publicKey = "xxx";
        // 私钥
        String privateKey = "xxx";
        // 明文内容
        String content = "test123456helloWorld";
        // 使用公钥,私钥初始化RSA对象
        RSA rsa = new RSA(privateKey, publicKey);
        // 公钥加密
        String encryptStr = rsa.encryptBase64(content, KeyType.PublicKey);
        System.out.println(encryptStr);
        // 私钥解密
        String plainText = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
        System.out.println(plainText);
    }

可以继续封装实现自己的签名/验签方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容