0


加密与安全_双向RSA+AES加密及Code实现

文章目录

在这里插入图片描述

AES / RSA

  • AES:一种对称加密算法,意味着加密和解密使用相同的密钥。速度快,适合加密大量数据。
  • RSA:一种非对称加密算法,有一对密钥:公钥和私钥。用公钥加密的数据只能用对应的私钥解密,反之亦然。

流程

在这里插入图片描述

  1. 客户端和服务端都生成一对RSA密钥:- 客户端和服务端各自生成自己的RSA公钥和私钥。- RSA公钥是公开的,可以共享;RSA私钥则要保密。
  2. 客户端和服务端分别生成AES密钥:- 客户端和服务端都生成自己的AES密钥,用于加密实际的数据。
  3. 客户端发送请求给服务端:- 客户端用服务端的RSA公钥加密它自己的AES密钥,并将加密后的AES密钥发送给服务端。- 同时,客户端还会用AES密钥加密一份请求报文,然后将这个加密的报文和它自己的RSA公钥一起发送给服务端。
  4. 服务端解密并处理请求:- 服务端接收到请求后,用自己的RSA私钥解密客户端发送的AES密钥。- 然后,服务端用解密后的AES密钥解密客户端的请求报文,得到了客户端发送的实际信息。- 服务端接下来会生成一个响应报文,用客户端的AES密钥加密该响应报文。
  5. 服务端发送响应给客户端:- 服务端用客户端的RSA公钥加密自己的AES密钥,并将加密后的AES密钥和加密的响应报文一起发送给客户端。
  6. 客户端解密并获取响应:- 客户端用自己的RSA私钥解密服务端发送过来的AES密钥。- 然后,客户端用解密后的AES密钥解密服务端的响应报文,得到最终的回应内容。

Code

在这里插入图片描述

生成AES密钥 和 生成RSA密钥对

packagecom.artisan.shuangxiang_aesrsa;importjavax.crypto.KeyGenerator;importjavax.crypto.SecretKey;importjava.security.KeyPair;importjava.security.KeyPairGenerator;/**
 * @author artisan
 */publicclassKeyGeneration{/**
     * 生成AES密钥
     *
     * @return 生成的SecretKey对象,包含AES算法的密钥
     * @throws Exception 如果密钥生成过程中出现错误
     */publicstaticSecretKeygenerateAESKey()throwsException{// 获取KeyGenerator实例,指定使用AES算法KeyGenerator keyGen =KeyGenerator.getInstance("AES");// 初始化AES密钥的长度为128位
        keyGen.init(128);// 生成AES密钥return keyGen.generateKey();}/**
     * 生成RSA密钥对
     *
     * @return 生成的RSA密钥对
     * @throws Exception 如果无法生成密钥对,则抛出异常
     */publicstaticKeyPairgenerateRSAKeyPair()throwsException{// 获取密钥对生成器实例KeyPairGenerator keyPairGen =KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器为2048位
        keyPairGen.initialize(2048);// 生成RSA密钥对return keyPairGen.generateKeyPair();}}

AES工具类,提供AES加密和解密功能

packagecom.artisan.shuangxiang_aesrsa;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.spec.IvParameterSpec;importjava.util.Base64;/**
 * @author artisan
 *//**
 * AES工具类,提供AES加密和解密功能
 * 使用AES/CBC/PKCS5Padding算法进行加密和解密
 */publicclassAESUtil{/**
     * 定义加密算法类型为AES/CBC/PKCS5Padding
     */privatestaticfinalStringALGORITHM="AES/CBC/PKCS5Padding";/**
     * 使用AES算法加密数据
     *
     * @param data 待加密的字符串
     * @param key 加密使用的SecretKey
     * @param iv 加密使用的初始化向量(IvParameterSpec)
     * @return 加密后的字符串,以Base64编码
     * @throws Exception 如果加密过程中发生错误,抛出异常
     */publicstaticStringencryptAES(String data,SecretKey key,IvParameterSpec iv)throwsException{// 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法Cipher cipher =Cipher.getInstance(ALGORITHM);// 初始化Cipher为加密模式,传入密钥和初始化向量
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);// 将待加密数据转换为字节数组,并执行加密操作byte[] encryptedData = cipher.doFinal(data.getBytes());// 将加密后的数据使用Base64编码,并返回returnBase64.getEncoder().encodeToString(encryptedData);}/**
     * 使用AES算法解密数据
     *
     * @param encryptedData 待解密的字符串,以Base64编码
     * @param key 解密使用的SecretKey
     * @param iv 解密使用的初始化向量(IvParameterSpec)
     * @return 解密后的字符串
     * @throws Exception 如果解密过程中发生错误,抛出异常
     */publicstaticStringdecryptAES(String encryptedData,SecretKey key,IvParameterSpec iv)throwsException{// 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法Cipher cipher =Cipher.getInstance(ALGORITHM);// 初始化Cipher为解密模式,传入密钥和初始化向量
        cipher.init(Cipher.DECRYPT_MODE, key, iv);// 将待解密数据从Base64解码为字节数组byte[] decodedData =Base64.getDecoder().decode(encryptedData);// 执行解密操作byte[] decryptedData = cipher.doFinal(decodedData);// 将解密后的数据转换为字符串,并返回returnnewString(decryptedData);}}

RSA加密工具类

packagecom.artisan.shuangxiang_aesrsa;importjavax.crypto.Cipher;importjava.security.PrivateKey;importjava.security.PublicKey;importjava.util.Base64;/**
 * RSA加密工具类
 * @author artisan
 */publicclassRSAUtil{/**
     *  定义加密算法类型为RSA
     */privatestaticfinalStringALGORITHM="RSA";/**
     * 使用RSA算法和公钥加密数据
     *
     * @param data 待加密的字符串数据
     * @param publicKey 用于加密的公钥
     * @return 加密后的数据,以Base64编码的字符串形式表示
     * @throws Exception 如果加密过程中发生错误,抛出异常
     */publicstaticStringencryptRSA(String data,PublicKey publicKey)throwsException{// 获取Cipher实例,指定使用RSA算法Cipher cipher =Cipher.getInstance(ALGORITHM);// 初始化Cipher为加密模式,并使用指定的公钥
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);// 将待加密的字符串转换为字节数组,并执行加密操作byte[] encryptedData = cipher.doFinal(data.getBytes());// 将加密后的字节数组使用Base64编码为字符串returnBase64.getEncoder().encodeToString(encryptedData);}/**
     * 使用RSA算法和私钥解密数据
     *
     * @param encryptedData 待解密的字符串数据,预期是通过Base64编码的
     * @param privateKey 用于解密的私钥
     * @return 解密后的原始字符串数据
     * @throws Exception 如果解密过程中发生错误,抛出异常
     */publicstaticStringdecryptRSA(String encryptedData,PrivateKey privateKey)throwsException{// 获取Cipher实例,指定使用RSA算法Cipher cipher =Cipher.getInstance(ALGORITHM);// 初始化Cipher为解密模式,并使用指定的私钥
        cipher.init(Cipher.DECRYPT_MODE, privateKey);// 将Base64编码的字符串解码为字节数组byte[] decodedData =Base64.getDecoder().decode(encryptedData);// 执行解密操作,得到原始的字节数组byte[] decryptedData = cipher.doFinal(decodedData);// 将解密后的字节数组转换为字符串returnnewString(decryptedData);}}

测试类

packagecom.artisan.shuangxiang_aesrsa;importjavax.crypto.SecretKey;importjavax.crypto.spec.IvParameterSpec;importjava.security.KeyPair;importjava.security.PrivateKey;importjava.security.PublicKey;importjava.util.Base64;/**
 * @author artisan
 */publicclassMain{/**
     * 使用RSA公钥加密AES密钥,以及使用RSA私钥解密AES密钥的全过程
     * 同时展示了使用AES密钥加密和解密数据的应用
     *
     * @param args 命令行参数
     * @throws Exception 可能抛出的异常
     */publicstaticvoidmain(String[] args)throwsException{// 生成AES和RSA密钥SecretKey aesKey =KeyGeneration.generateAESKey();KeyPair rsaKeyPair =KeyGeneration.generateRSAKeyPair();PublicKey rsaPublicKey = rsaKeyPair.getPublic();PrivateKey rsaPrivateKey = rsaKeyPair.getPrivate();String aesKeyString =Base64.getEncoder().encodeToString(aesKey.getEncoded());System.out.println("AES密钥: "+ aesKeyString);// 初始化IV(通常需要确保IV的安全传输)  16字节的IV向量IvParameterSpec iv =newIvParameterSpec(newbyte[16]);// 客户端用服务端的RSA公钥加密AES密钥String encryptedAESKey =RSAUtil.encryptRSA(aesKeyString, rsaPublicKey);System.out.println("加密后的AES密钥: "+ encryptedAESKey);// 模拟服务端解密AES密钥String decryptedAESKey =RSAUtil.decryptRSA(encryptedAESKey, rsaPrivateKey);SecretKey originalAESKey =newjavax.crypto.spec.SecretKeySpec(Base64.getDecoder().decode(decryptedAESKey),"AES");System.out.println("解密后的AES密钥: "+Base64.getEncoder().encodeToString(originalAESKey.getEncoded()));// 使用AES加密和解密数据String originalData ="我是需要加密的数据artisan GO GO GO !!!";String encryptedData =AESUtil.encryptAES(originalData, aesKey, iv);System.out.println("加密的数据: "+ encryptedData);String decryptedData =AESUtil.decryptAES(encryptedData, aesKey, iv);System.out.println("解密的数据: "+ decryptedData);}}

输出

AES密钥: n5PbFsDPACXiDsuBhjHwvg==
加密后的AES密钥: cuNuyggZpGhVthHpUPEEt7l7Nh9ySl4S4zLBVLpxbx3ft9JwKNfTi0ggtAX1p27lpFsru/riYVv/6HuI/AO2PV/WzmE9ySUa7+cdkvlTqdbsQaFF67R2DqEtMbsJyfiGVI6Y9acObMWw9nGeggtsQAlfNqjV8LC8i1T4OJcstMcmdgCEg85vBizwdFEOJPZO1SDEd///CY2jT7tY7Zz4kvq9f+WkNnHy+s11cUOzr6Griv83JlFNPvJ3DifVhkmxsR5Cg9HaRtjSRvx9VPfwza/SrQWue7rzsLSirXsj+kIOBfOopSFj0xSBCG32NnQEuWspSGdgJTHAmD/X7RJzoQ==
解密后的AES密钥: n5PbFsDPACXiDsuBhjHwvg==
加密的数据: a1gn+70y0nkd9VGg3hg3Y/b0PxUd1dqAuzKHDedGMdleu2UVWkBtInZ0Ox4iNOFM
解密的数据: 我是需要加密的数据artisan GOGOGO!!!

总结

这个流程的核心在于:

  • 使用RSA来安全地交换AES密钥
  • AES用来加密实际的数据,确保数据传输的安全性和效率
  • 请注意保护好自己的私钥,不可泄露

通过这种双向加密的方式,客户端和服务端能够安全地互相传递敏感信息,同时确保即使通信内容被截获,也无法被解读。

在这里插入图片描述


本文转载自: https://blog.csdn.net/yangshangwei/article/details/141361253
版权归原作者 小小工匠 所有, 如有侵权,请联系我们删除。

“加密与安全_双向RSA+AES加密及Code实现”的评论:

还没有评论