AES加密解密的使用方法

7,478 阅读3分钟

理解AES加密解密的使用方法

背景

公司之前的项目,后端采用的是 AES + BASE64 算法加密,前端重构,一通乱折腾,终于搞出来了,芜湖起飞~~~~~~~~~~~~~~~~~~~~~~~~~~ 先写出掘文,供各位掘友参考

目前前端加密的方式有

1、MD5加密(如果是16位和32位字符就首先怀疑是md5)关键字md5

2、DES/AES加密:是一种使用密钥加密的算法,叫做对称加密方式,现在主要使用AES代替DES

AES密文长度是8的整数倍,DES是长度16的整数倍,关键字:CryptoJS.AES CryptoJS.DES

3、RSA加密:非对称加密算法。需要两个密钥:公开密钥(publickey)和私有密钥(privatekey),成对出现,一般看后面有两个==,一般用于电商和邮件网站,关键字 publickey privatekey

用公钥加密,用私钥解密。

4、Base64伪加密,是一种用64个字符来表示任意二进制数据的方法。base64是一种编码方式,而不是加密算法。只是看上去像加密,关键字:base64

5、https证书密钥加密,网络上传输的数据加密。SSL证书

今天就搞一搞AES加密,AES属于块加密,对越长的字符串进行加密,代价越大,所以通常对明文进行分段,然后对每段明文进行加密,最后再拼成一个字符串。块加密的一个要面临的问题就是如何填满最后一块?所以这就是PADDING的作用,使用各种方式填满最后一块字符串,所以对于解密端,也需要用同样的PADDING来找到最后一块中的真实数据的长度。加密模式很多,ECB,CBC,CFB等等,这些模式除了ECB由于没有使用IV而不太安全,其他模式差别并没有太明显,大部分的区别在IV和KEY来计算密文的方法略有区别。具体可参考WIKI的说明。另外,AES分为AES128,AES256,Pkcs7等,表示期待秘钥的长度,比如AES256秘钥的长度应该是256/8的32字节,一些语言的库会进行自动截取,让人以为任何长度的秘钥都可以。而这其实是有区别的。

正文

加密

前端首先需要引入

import CryptoJS from "crypto-js";

// 加密 plaintText 明文密码,key 秘钥 ,iv 钥偏移量

var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {
iv,

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

});

我们可以看到加解密时需要秘钥(key)和秘钥偏移量(iv),这两个需要前后端定义好。
由于Java就是按照128bit给的,但是由于是一个字符串,需要先在前端将其转为128bit的才行。
,需要使用CryptoJS.enc.Utf8.parse方法才可以将key转为128bit的。(这个地方由于前后端不一样,花了好长时间,这里是关键),key和iv都需要用使用CryptoJS.enc.Utf8.parse方法转换。

由于CryptoJS生成的密文是一个对象,如果直接将其转为字符串是一个Base64编码过的,在encryptedData.ciphertext上的属性转为字符串才是后端需要的格式。

var encryptedBase64Str = encryptedData.toString();

// 需要读取encryptedData上的ciphertext.toString()才能拿到跟Java一样的密文

var encryptedStr = encryptedData.ciphertext.toString();

console.log(encryptedStr);
解密
/**
 * AES解密(CBC,Pkcs7)
 */
export function decrypt_cbc(word: string) {
    var decrypt = CryptoJS.AES.decrypt(word, key, {
        iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    //解密后,需要按照Utf8的方式将明文转位字符串
    var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
   
    return decryptedStr;
}