[Java]RSA非对称加解密工具类代码实现

2021-04-14 1216点热度 0人点赞 0条评论

前言

本篇简单介绍下非对称加密以及公钥和私钥加密不同的使用场景,以及如何用Java代码实现AES加解密的工具类和例子

非对称加密简介

需要两个密钥(公钥和私钥)来进行加密和解密,公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥) ,公钥加密的信息只有私钥才能解开,私钥加密的信息只有公钥才能解开。这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,所以只要私钥不泄露,那么我

  • 对于签名:私钥加密,公钥解密。好比你的签名只有你自已签的才是真的,别人签的都是假的。

们的数据就是安全的。

公钥加密或私钥加密

  • 对于加密:公钥加密,私钥加密。毕竟公钥可以公开,但是私钥只有你自已知道,你也同样希望只有你自已才能解密
  • 对于签名:私钥加密,公钥解密。好比你的签名只有你自已签的才是真的,别人签的都是假的。

Java实现常用的AES非对称加解密工具类

RSA 算法是非对称加解密中比较常用的加密算法,基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

在加载的时候PKCS#1 format的私钥的时候,可能会报错,需要加如下maven依赖,我在代码里loadPrivateKey也有说明

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.58</version>
</dependency>

下面直接上干货,测试代码,写在main方法里了,其他说明写在注释里。

如有需要Javascript版本的RSA加解密,请看 https://blog.terrynow.com/2021/04/20/javascript-tool-rsa-encrypt-implement/

RSAUtil.java

package com.terrynow.test;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @author Terry E-mail: yaoxinghuo at 126 dot com
 * @date 2021-4-14 10:51
 * @description
 */
public class RSAUtil {
    public static void main(String[] args) throws Exception {

        PrivateKey privateKey = loadPrivateKey("-----BEGIN RSA PRIVATE KEY-----\n" +
                "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJlTlMmhFxhVZ/U6xd3\n" +
                "TZTelu0g8a+tZYAqoOegsJXXlelthlLTzx5qkWEf4STjIMaIYtduIO1xVs1L3Gsjyl3\n" +
                "IhofjuVwI2qk2QVCtuVXkDvO/gPXCzur5iTDCG7Jrh5jJI5VtaVGHVH37TSWUYiowKv\n" +
                "SzdKViPQ1h1J/BPewI5AgMBAAECgYAwBq4kOgEx7g6SEcbIpN6ff5oaFlL3dRdQP0Fk\n" +
                "J+/T7f1VgktCItny5meAo5TL5GknjPXpvdJaKb3xztTk/JfS+X4uZBuEumb+UV8hWzJ\n" +
                "0hvxIMtVf0rwFLbEB6btiNJHDCIv2+eJSEoK2RjYF/qGb0zzFz1YGICY5Vjl2TDnlwQ\n" +
                "JBAPHbqEWKT1KeEXKzNBcZadglfjF+qXQmWFGN3yUrd8Xxmet+oKfhXgPgybfo8/uwM\n" +
                "6ijJaEYNWWU6wbvMf9jkZ8CQQCiSrTLyzEe9pObKpwGk3U2jkaYOnSKdMYebxvF9BGN\n" +
                "CnLsen0rDOefgHGNwUMphzWaqWESnb1TB7Mck/kanU0nAkEA3D1Zg1HKoAI/A0L62Vo\n" +
                "UD3c87hdYeeN9I27c1/04SXGT52XdKGNKeJ+XMTkaDITM1fETEBp6bXFpgFwLHHRwIw\n" +
                "JBAKExPFOyNM7BMCiM8L2jVmdidwGaBcjDZUgzKU27Nnd06mKw4oOQ5LnKtH6Mdy3XK\n" +
                "sm79DuuSq4eVqtK2b+yfz8CQQC7frRjmYPe9+2JrTWMbzfFlLysCn7xmdbW5rVCs8sO\n" +
                "5jq8YxW5nV99IVGaKjYw6wcjIGut9uZw6Mmec05CODzh\n" +
                "-----END RSA PRIVATE KEY-----");

        PublicKey publicKey = loadPublicKey("-----BEGIN PUBLIC KEY-----\n" +
                "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZU5TJoRcYVWf1OsXd02U3pbtIPGv\n" +
                "rWWAKqDnoLCV15XpbYZS088eapFhH+Ek4yDGiGLXbiDtcVbNS9xrI8pdyIaH47lcCNq\n" +
                "pNkFQrblV5A7zv4D1ws7q+Ykwwhuya4eYySOVbWlRh1R9+00llGIqMCr0s3SlYj0NYd\n" +
                "SfwT3sCOQIDAQAB\n" +
                "-----END PUBLIC KEY-----");

//        KeyPair keyPair = buildKeyPair();
//        String privateString = base64Encode(keyPair.getPrivate().getEncoded());
//        String publicString = base64Encode(keyPair.getPublic().getEncoded());
//        System.out.println("private:");
//        System.out.println(privateString);
//        System.out.println("public:");
//        System.out.println(publicString);

        byte[] encrypted = encrypt(publicKey, "This is a test!");
        System.out.println(base64Encode(encrypted));

        byte[] bytes = decrypt(privateKey, base64Decode("VX1x8DRvRyvklwXPCXzUgg7eZx7j8wQ2ZdwLSv68rHIk4PAkdwXvk+7WHgG8R27Xq8u2Q/5V6Yrji43EqD7b02JjjYlN1XbfjiJvP4HoBR8yTgjOrhXBd3N+fIhEl6B7CYCaEVdQtL32q7x+CKDIlZbnTt1E3ofCtAc17/H8m8s="));
        System.out.println(new String(bytes));
    }

    public static final String RSA_ALGORITHM = "RSA";

    /**
     * 成功密钥对
    */
    public static KeyPair buildKeyPair() throws NoSuchAlgorithmException {
        final int keySize = 1024;
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        keyPairGenerator.initialize(keySize);
        return keyPairGenerator.genKeyPair();
    }

    /**
     * 用私钥加密
     */
    public static byte[] encrypt(PrivateKey privateKey, String message) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

        return cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 用公钥加密
     */
    public static byte[] encrypt(PublicKey publicKey, String message) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        return cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 用公钥解密
     */
    public static byte[] decrypt(PublicKey publicKey, byte[] encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        return cipher.doFinal(encrypted);
    }

    /**
     * 用私钥解密
     */
    public static byte[] decrypt(PrivateKey privateKey, byte[] encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        return cipher.doFinal(encrypted);
    }

    /**
     * 从文本中加载公钥
     */
    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
        String string = publicKeyStr
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s", "");
        byte[] buffer = base64Decode(string);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        return keyFactory.generatePublic(keySpec);
    }

    /**
     * 从文本中加载私钥
     */
    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
//        PKCS#1 format 格式的私钥会报错,需要假如如下addProvider,maven需要添加如下dependency
//        <dependency>
//			<groupId>org.bouncycastle</groupId>
//			<artifactId>bcprov-jdk15on</artifactId>
//			<version>1.58</version>
//		</dependency>
        java.security.Security.addProvider(
                new org.bouncycastle.jce.provider.BouncyCastleProvider()
        );

        String string = privateKeyStr
                .replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "")

                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")

                .replaceAll("\\s", "");
        byte[] buffer = base64Decode(string);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    public static String base64Encode(byte[] data) {
        return Base64.getEncoder().encodeToString(data);
    }

    public static byte[] base64Decode(String data) {
        return Base64.getDecoder().decode(data);
    }

}

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论