java实践RSA+AES数据加密

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk18on</artifactId>
    <version>1.78.1</version>
</dependency>

代码

import static org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER\_NAME;

import lombok.SneakyThrows;

import org.apache.commons.lang3.tuple.Pair;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.\*;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/\*\*
 \* @author siyang
 \* @date 2024/4/29 11:29
 \* @description 加密工具类
 \*/
public class EncryptUtils {
    /\*
 将 BouncyCastleProvider 添加到Java的安全提供者列表中,之后就可以通过 "BC" 引用它来获取或实例化加密算法等组件
 如 Cipher.getInstance("AES/ECB/PKCS7Padding", "BC")
 \*/
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String AES\_ALGORITHM = "AES";
    private static final String RSA\_ALGORITHM = "RSA";
    private static final String AES\_ALGORITHM\_MODEL = "AES/ECB/PKCS5Padding";

    /\* ============================== AES: 加密业务数据 ============================== \*/

    /\*\*
 \* 获取Aes密钥。
 \*
 \* @param keySize 密钥长度,可选值:128, 192;理论可填写256,由于返回时会对字节进行base64编码,无形中扩大了字节数,所以实际选择128、192
 \* @return base64格式密钥
 \*/
    @SneakyThrows
    public static String createAesKey(int keySize) {
        KeyGenerator keygen = KeyGenerator.getInstance(AES\_ALGORITHM);
        keygen.init(keySize);
        SecretKey secretKey = keygen.generateKey();
        byte[] byteKey = secretKey.getEncoded();
        return Base64.getEncoder().encodeToString(byteKey);
    }

    /\*\*
 \* AES 加密
 \*
 \* @param content 需要加密的内容
 \* @param key aes密钥
 \* @return 加密后的密文
 \*/
    @SneakyThrows
    public static String aesEncrypt(String content, String key) {
        Cipher cipher = Cipher.getInstance(AES\_ALGORITHM\_MODEL, PROVIDER\_NAME);
        SecretKeySpec secretKeySpec =
                new SecretKeySpec(key.getBytes(StandardCharsets.UTF\_8), AES\_ALGORITHM);
        cipher.init(Cipher.ENCRYPT\_MODE, secretKeySpec);

        byte[] encryptedBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF\_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /\*\*
 \* AES 解密
 \*
 \* @param encryptedContent 已加密的密文
 \* @param key aes密钥,必须与加密时使用的密钥一致
 \* @return 解密后的内容
 \*/
    @SneakyThrows
    public static String aesDecrypt(String encryptedContent, String key) {
        Cipher cipher = Cipher.getInstance(AES\_ALGORITHM\_MODEL, PROVIDER\_NAME);
        SecretKeySpec secretKeySpec =
                new SecretKeySpec(key.getBytes(StandardCharsets.UTF\_8), AES\_ALGORITHM);
        cipher.init(Cipher.DECRYPT\_MODE, secretKeySpec);

        byte[] decodedBytes =
                Base64.getDecoder().decode(encryptedContent.getBytes(StandardCharsets.UTF\_8));
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF\_8);
    }

    /\* ============================== RSA: 加密AES密钥 ============================== \*/

    /\*\*
 \* 生成rsa密钥对
 \*
 \* @param keySize 密钥长度
 \* @return 密钥对:left:公钥; right:私钥
 \*/
    @SneakyThrows
    public static Pair<String, String> createPemRsaKeyPair(int keySize) {
        String pemPublicKeyFormat = "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----";
        String pemPrivateKeyFormat = "-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----";
        KeyPairGenerator generator = KeyPairGenerator.getInstance(RSA\_ALGORITHM, PROVIDER\_NAME);
        generator.initialize(keySize);
        KeyPair kp = generator.generateKeyPair();
        String publicKey =
                Base64.getEncoder()
                        .encodeToString(kp.getPublic().getEncoded())
                        .replaceAll("(.{64})", "$1\n");
        String privateKey =
                Base64.getEncoder()
                        .encodeToString(kp.getPrivate().getEncoded())
                        .replaceAll("(.{64})", "$1\n");
        return Pair.of(
                String.format(pemPublicKeyFormat, publicKey),
                String.format(pemPrivateKeyFormat, privateKey));
    }

    /\*\*
 \* 使用公钥加密数据
 \*
 \* @param pemPublicKey pem格式公钥
 \* @param content 待加密的数据
 \* @return 加密后的数据Base64编码字符串
 \*/
    @SneakyThrows
    public static String rsaEncrypt(String content, String pemPublicKey) {
        byte[] publicKeyBytes = parsePemKey(pemPublicKey);
        KeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA\_ALGORITHM, PROVIDER\_NAME);
        PublicKey key = keyFactory.generatePublic(keySpec);

        Cipher cipher = Cipher.getInstance(RSA\_ALGORITHM);
        cipher.init(Cipher.ENCRYPT\_MODE, key);

        byte[] encryptedBytes = cipher.doFinal(content.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /\*\*
 \* 使用私钥解密数据
 \*
 \* @param pemPrivateKey pem格式私钥
 \* @param encryptedContent 加密后的数据Base64编码字符串
 \* @return 原始数据字符串
 \*/
    @SneakyThrows
    public static String rsaDecrypt(String encryptedContent, String pemPrivateKey) {
        byte[] privateKeyBytes = parsePemKey(pemPrivateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA\_ALGORITHM, PROVIDER\_NAME);
        PrivateKey key = keyFactory.generatePrivate(keySpec);

        Cipher cipher = Cipher.getInstance(RSA\_ALGORITHM);
        cipher.init(Cipher.DECRYPT\_MODE, key);

        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedContent);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF\_8);
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**

![img](https://img-blog.csdnimg.cn/img_convert/4f0cdd7f4581275ae97fb802a92c9251.png)

![img](https://img-blog.csdnimg.cn/img_convert/0fc447f70028fed21350ed3cdc7aff8b.png)

![img](https://img-blog.csdnimg.cn/img_convert/ba4097a65862d3eb7c6693c11fe45e7b.png)

![img](https://img-blog.csdnimg.cn/img_convert/6e2c942491f0b359cf9eed714c5d2d77.png)

![img](https://img-blog.csdnimg.cn/img_convert/b6731115865943d899948984f3bcb5ce.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值