0


RSA与AES:打造高效且超安全的混合加密方案

RSA + AES 混合加密

RSA非对称加密的一种,具有两个密钥:公共密钥和私有密钥。公钥和私钥是一对,公钥加密后的内容只有私钥才能解密。两个密钥的不同,所以是非对称的。

AES对称加密的一种,加密和解密的密钥都是一个

由此就可以看出两者的优势和劣势:

RSA相对安全,但是加密速度则会慢;而AES加密速度快,但是安全性相对差。

下面直接用登录功能的前后端交互图作为案例:

在这里插入图片描述

而后就是对应的工具库的问题,有很多可以实现加密的工具。但是前后端需要能用一样的加密和解密的算法才行。

RSA工具库:

RSA/ECB/PKCS1Padding,这个是RSA算法的具体实现方式,这个有很多种,比如还有ECB因此很容易和别人的算法不匹配。

  • ECB 模式 在 RSA 加密中使用是安全的,因为 RSA 加密的主要对象是小数据块(如会话密钥),而不是大数据量的数据块。
  • PKCS1Padding 提供了额外的安全性,确保加密的数据块长度合适,并防止某些攻击,如小明文本攻击。

这里看了别人的文章补充一下:

  • Java 默认的 RSA 实现是 RSA/None/PKCS1Padding
  • 在创建RSA秘钥对时,长度最好选择 2048的整数倍,长度为1024在已经不很安全了
  • DER是RSA密钥的二进制格式,PEM是DER转码为Base64的字符格式,用PEM比较通用,字符串方便阅读。

后端代码:

importjava.security.*;importjava.security.spec.PKCS8EncodedKeySpec;importjavax.crypto.Cipher;importjava.util.Base64;publicclassRSADecrypt{publicstaticStringdecrypt(String encryptedText,String privateKey)throwsException{byte[] encryptedBytes =Base64.getDecoder().decode(encryptedText);byte[] privateKeyBytes =Base64.getDecoder().decode(privateKey);PKCS8EncodedKeySpec keySpec =newPKCS8EncodedKeySpec(privateKeyBytes);KeyFactory keyFactory =KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);Cipher cipher =Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);byte[] decryptedBytes = cipher.doFinal(encryptedBytes);returnnewString(decryptedBytes);}publicstaticvoidmain(String[] args)throwsException{// 生成RSA密钥对// 使用自定义的种子值来初始化 KeyPairGeneratorbyte[] seed ="RSA".getBytes();// 用自己想要的值替换这里的固定种子值KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048,newSecureRandom(seed));KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 将公钥和私钥转换成Base64编码的字符串,以便传递给前端和后端String publicKeyString =Base64.getEncoder().encodeToString(publicKey.getEncoded());String privateKeyString =Base64.getEncoder().encodeToString(privateKey.getEncoded());}

前端RSA工具库(加密):

“jsencrypt”: “^3.3.2”

import JsEncrypt from'jsencrypt'var encrypt =newJsEncrypt();

encrypt.setPublicKey();this.encryptedAesKey = encrypt.encrypt()

AES工具类后端:

AES/ECB/PKCS5Padding 注意算法方式

importorg.apache.commons.codec.DecoderException;importorg.apache.commons.codec.binary.Hex;importjavax.crypto.*;importjavax.crypto.spec.SecretKeySpec;importjava.io.UnsupportedEncodingException;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;/**
 * AES对称加密工具类
 */publicclassAESUtil{/**
     * 加密算法
     */privatestaticStringAlgorithm="AES";/**
     * 算法/模式/补码方式
     */privatestaticStringAlgorithmProvider="AES/ECB/PKCS5Padding";/**
     * 加密
     *
     * @param src       原内容
     * @param uniqueKey 唯一key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws DecoderException
     */publicstaticStringencrypt(String src,String uniqueKey)throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,BadPaddingException,IllegalBlockSizeException,DecoderException{byte[] key = uniqueKey.getBytes();SecretKey secretKey =newSecretKeySpec(key,Algorithm);Cipher cipher =Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] cipherBytes = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));returnbyteToHexString(cipherBytes);}/**
     * 解密
     *
     * @param enc       加密内容
     * @param uniqueKey 唯一key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws DecoderException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */publicstaticStringdecrypt(String enc,String uniqueKey)throwsNoSuchPaddingException,NoSuchAlgorithmException,UnsupportedEncodingException,InvalidAlgorithmParameterException,InvalidKeyException,DecoderException,BadPaddingException,IllegalBlockSizeException{byte[] key = uniqueKey.getBytes();SecretKey secretKey =newSecretKeySpec(key,Algorithm);Cipher cipher =Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] hexBytes =hexStringToBytes(enc);byte[] plainBytes = cipher.doFinal(hexBytes);returnnewString(plainBytes,"UTF-8").replaceAll("^\"|\"$","");}/**
     * 将byte数组转换为16进制字符串
     *
     * @param src
     * @return
     */privatestaticStringbyteToHexString(byte[] src){returnHex.encodeHexString(src);}/**
     * 将16进制字符串转换为byte数组
     *
     * @param hexString
     * @return
     */privatestaticbyte[]hexStringToBytes(String hexString)throwsDecoderException{returnHex.decodeHex(hexString);}}

AES前端代码:

//生成指定长度随机字符串generateRandomStr(strLength =16){let code ='';const chars ='abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';const charsArr = chars.split('');for(let i =0; i < strLength; i++){const num = Math.floor(Math.random()* charsArr.length);
        code += charsArr[num];}return code;},
const encryptedContent_zh = CryptoJS.AES.encrypt(content_zh,this.key,{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7
        });const encStr_zh = encryptedContent_zh.ciphertext.toString();this.encStr_zh = encryptedContent_zh.ciphertext.toString();const encryptedContent_mm = CryptoJS.AES.encrypt(content_mm,this.key,{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7
        });// 解密方法const decryptedContent_zh = CryptoJS.AES.decrypt(
          CryptoJS.format.Hex.parse(encStr_zh),this.key,//注意:后面这里最好使用 CryptoJS.format.Utf8.parse(key) {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7
          });
标签: 安全 java RSA

本文转载自: https://blog.csdn.net/weixin_72926030/article/details/139047577
版权归原作者 是小钱- 所有, 如有侵权,请联系我们删除。

“RSA与AES:打造高效且超安全的混合加密方案”的评论:

还没有评论