Java实现RSA加密和解密

举报
大胖花 发表于 2021/01/11 10:21:25 2021/01/11
【摘要】 使用OpenSSL生成密钥对(公钥和私钥),使用java代码对字符串进行加密解密。使用公钥加密,可以使用私钥解密,反之也可以。1.安装OpenSSL并生成密钥官网:https://www.openssl.org/Windows安装包下载:https://oomake.com/download/openssl安装完成后打开\OpenSSL-Win64\bin\openssl.exe生成密钥文件...

使用OpenSSL生成密钥对(公钥和私钥),使用java代码对字符串进行加密解密。
使用公钥加密,可以使用私钥解密,反之也可以。

1.安装OpenSSL并生成密钥

官网:https://www.openssl.org/
Windows安装包下载:
https://oomake.com/download/openssl
安装完成后打开\OpenSSL-Win64\bin\openssl.exe
生成密钥文件:

genrsa -des3 -out lizheblogs_privkey.pem 2048

如果不需要密码,去掉-des3

输出私钥内容:

rsa -in lizheblogs_private_key.pem

输出公钥内容:

rsa -in lizheblogs_private_key.pem -pubout

内容类似于:

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvKeg42T4bPvh1tjPXrwLQH34zy7KlDWtlHL2RGK4mGiV3f2V
CViNvHJGfjTCUjypBGxN3hR32ubEBYeShfieVHljEPZwfJ80R0D2Z1OZRc/weQfh
rqGFXCls+kvLiN0x45PDywZC3SmNyqJsLrvX7C3NcBUfSmOX3L0YjqsYtvkK4Frt
O5j4h/sDxfdsPzKcQ3G54lGNLCU2h8JTeqIBISAFysAxXitHxM03OfwGXet1KHoj
stAmtPz/CFJ8QRO0LT21qrzclMA9mzP6A13BMUmEwUMjpSqocLU7YCXEMEjC+4dB
uoHWRXuEC4XKlPoiZMNY+RLNsDoAX3IpA6Et1QIDAQABAoIBAFC9LQ4k2G1MH4tj
ntxcfjRLtYB19h0YHAG8cckytu4DVKB9NpuZWo+cGK9KxR+M9oj+ERVKjUESIjJ7
oynTDW/5w3wu/FVZjXYxR0NRc/d81t31kZC7b+fRkuJMLf+VKxTK2LC7LUKZ1iUy
/jnCCtb5g0LEx29+0C+YfjoQ37LuhoG657VFyKiFNKt26m0f9cpURs9EyHjv290v
HoZ5sBIgubPRWxhNV33DIDTJ1fQX+EEFyC637z6XKCar6JgOwUhBJwagVnzxxdsq
kpnTidpjuKCuDfAq+mQzprLnw0H7Mhxps1ZwoUA2KmTMC52noChZShirWqZMZsbh
tsKWdMECgYEA5VkuxwZeBNn6DKslqhkDTO0oEnns117hSxgZ9nq6FwEhTS+HTuzU
TwVO5naD0O4xOYFXrH7DvPxFtufV3lyAeuUc0jPnpsBobwWCMra6ENyhxEh3ayV5
DTSvHPvNCoXaxqfWSMPZhvfjF5v3kq5HzNLHN3DF0s8AzXhHhf7Y54sCgYEA0pPd
WZxaqRI0GnBvtwN6yJk53ykzR5DgbP8cNV9770Y/vrLHbMvN/gzLljRDZFUrAXLf
NJHyurYsx1fxc6cG8c51cxeM8vhWnPXthwDv4rtXHN9AamLX6tTLdYPnfdks0Qfv
6oE1dK40AB+djF36WYNw79zOMOXVC5bqZxrb7B8CgYB1BGHHjkoeM5FPMWuQNB7o
+v+9HZRn9rMAe5WTmt6jqiHxndRtwow4nT66e7GZwk4/Ru0Sx8LbA+QWBIesYonz
Kj7gSTdibz1Zl/fsJCsfO1MWMNstQftXb5ABO8BMJCuRvESq77JnGMc3Xo6cumtL
6CdY9CMbAh8otrvXdEX7LQKBgD7FdSZRRXVAx+dZvPOBRgimJGoxjee3eC8FnRML
85XQCxB9mpUD69PfXJDZ43z1Jmy4IXE6UHD3/UEvJfqjv541PS2hx5JmFOuVI8kq
rleYIM+qfTk5XcPSyxOszkTliEaHZy0wdw7hHv8qbXx6RzaHyBK4b36EBI3/3r/9
cbFhAoGAfc9OGTcM/Nps1zVPxMuBxfW9VxVJSlvo8nGeYDRGqysoj9h7xwuYK7zM
L1NNccEyatJCWscN+nN5LdS6tg9oxgQvLv47p8WVD4Dl+Ow9Mes8rhev8OUkpBwe
VsB0sql+OGeeTnfRIxfSzrTqmwP2D8yD3N0H0vHTgcGr9Koh8tk=
-----END RSA PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvKeg42T4bPvh1tjPXrwL
QH34zy7KlDWtlHL2RGK4mGiV3f2VCViNvHJGfjTCUjypBGxN3hR32ubEBYeShfie
VHljEPZwfJ80R0D2Z1OZRc/weQfhrqGFXCls+kvLiN0x45PDywZC3SmNyqJsLrvX
7C3NcBUfSmOX3L0YjqsYtvkK4FrtO5j4h/sDxfdsPzKcQ3G54lGNLCU2h8JTeqIB
ISAFysAxXitHxM03OfwGXet1KHojstAmtPz/CFJ8QRO0LT21qrzclMA9mzP6A13B
MUmEwUMjpSqocLU7YCXEMEjC+4dBuoHWRXuEC4XKlPoiZMNY+RLNsDoAX3IpA6Et
1QIDAQAB
-----END PUBLIC KEY-----

2.java加密解密代码

package com.lizheblogs.server.utils;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 * Created by LiZhe on 2020-10-27.
 * com.lizheblogs.server.utils
 */
@Component
public class RSAEncrypt {

    private static String privateKey;
    private static String publicKey;

    public RSAEncrypt() {
        java.security.Security.addProvider(
                new org.bouncycastle.jce.provider.BouncyCastleProvider()
        );
    }

    @Value("${constants.private-key}")
    public void setPrivateKey(String privateKey) {
        RSAEncrypt.privateKey = privateKey;
    }

    @Value("${constants.public-key}")
    public void setPublicKey(String publicKey) {
        RSAEncrypt.publicKey = publicKey;
    }

    /**
     * RSA公钥加密
     * 对应解密方法:{@link RSAEncrypt#decryptPrivate(java.lang.String)}
     *
     * @param str 加密字符串
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encryptPublic(String str) throws Exception {
        return encrypt(str, getRsaPublicKey());

    }

    /**
     * RSA私钥解密
     * 对应加密方法:{@link RSAEncrypt#encryptPublic(java.lang.String)}
     *
     * @param str 加密字符串
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String decryptPrivate(String str) throws Exception {
        return decrypt(str, getRsaPrivateKey());
    }

    /**
     * RSA私钥加密
     * 对应解密方法:{@link RSAEncrypt#decryptPublic(java.lang.String)}
     *
     * @param str 加密字符串
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encryptPrivate(String str) throws Exception {
        return encrypt(str, getRsaPrivateKey());
    }

    /**
     * RSA公钥解密
     * 对应加密方法:{@link RSAEncrypt#encryptPrivate(java.lang.String)}
     *
     * @param str 加密字符串
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String decryptPublic(String str) throws Exception {
        return decrypt(str, getRsaPublicKey());

    }

    /**
     * 解析私钥
     *
     * @return 私钥
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static RSAPrivateKey getRsaPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String privateKeyContent = privateKey.replaceAll("\\n", "")
                .replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "");

        KeyFactory kf = KeyFactory.getInstance("RSA");

        PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(java.util.Base64.getDecoder().decode(privateKeyContent));
        return (RSAPrivateKey) kf.generatePrivate(keySpecPKCS8);
    }

    /**
     * 解析公钥
     *
     * @return 公钥
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static RSAPublicKey getRsaPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        //解析公钥
        String publicKeyContent = publicKey.replaceAll("\\n", "")
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "");

        KeyFactory kf = KeyFactory.getInstance("RSA");

        X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(java.util.Base64.getDecoder().decode(publicKeyContent));
        return (RSAPublicKey) kf.generatePublic(keySpecX509);
    }

    /**
     * 解密
     *
     * @param str 加密字符串
     * @param key 密钥
     * @return 文字
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    private static String decrypt(String str, Key key) throws NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(inputByte));
    }

    /**
     * 加密
     *
     * @param str 文字
     * @param key 密钥
     * @return 加密字符串
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    private static String encrypt(String str, Key key) throws NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
    }
}

测试方法:

String encrypt = RSAEncrypt.encryptPublic("pulqueli@gmail.com");
System.out.println("====" + encrypt);
String decrypt = RSAEncrypt.decryptPrivate(encrypt);
System.out.println("====" + decrypt);



参考文献:
https://blog.csdn.net/ls0111/article/details/77533768
https://gist.github.com/destan/b708d11bd4f403506d6d5bb5fe6a82c5
https://blog.csdn.net/qy20115549/article/details/83105736
https://blog.csdn.net/lwz15071387627/article/details/88103997

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。