同福

使用CryptoJS实现AES算法的CBC模式的加密/解密

问题

最近的项目遇到了前端需要加密数据的需求,了解了一下使用AES算法的是比较多的。那么使用什么方法在前端实现AES算法呢?后来发现前端的各种加密/解密的算法基本都被一个叫CryptoJS的包给垄断了!福哥捣鼓了一下,这个CryptoJS包确实很强大!

今天福哥就把这个使用CryptoJS实现AES算法的方法教给大家,有需要的可以拿去使用~

解决

准备

下载CryptoJS库,可以从官方的github上面下载,也可以通过npm来安装。

https://github.com/sytelus/CryptoJS

引入CryptoJS的md5库和aes库。

<script type="text/javascript" src="../js/libs/CryptoJS/rollups/md5.js"></script>
<script type="text/javascript" src="../js/libs/CryptoJS/rollups/aes.js"></script>

现在可以写代码了!准备一个需要加密的数据,和一个密钥。

// origin
console.log("====== prepare ======");
data = "码友:可以教教我如何使用CryptoJS库实现AES算法的前端加密/解密吗?我在tongfu.net上没有找到。";
passphrase = "福哥:好的!现在就弄!";
console.log("data:", data);
console.log("passphrase:", passphrase);

加密

这里是福哥写的一个AES+CBC的加密函数。

function aesEncrypt(data, passphrase){
    var key, iv, hKey, hIV, dataEncRes;
    // make key & iv
    key = CryptoJS.MD5(passphrase).toString();
    iv = key.substr(0, 16);
    hKey = CryptoJS.enc.Hex.parse(key);
    hIV = CryptoJS.enc.Hex.parse(iv);
    // encrypt
    dataEncRes = CryptoJS.AES.encrypt(
        data,
        hKey,
        {
            iv: hIV,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return dataEncRes;
}

现在福哥使用aesEncrypt这个函数来加密准备好的数据。

// encrypt
console.log("====== encrypt ======");
dataEncRes = aesEncrypt(data, passphrase);
dataEncStr = dataEncRes.toString();
dataEncCipherTextStr = dataEncRes.ciphertext.toString();
console.log("data encoded result:", dataEncRes);
console.log("data encoded string:", dataEncStr);
console.log("data encoded ciphertext:", dataEncCipherTextStr);

解密

这里是福哥写的一个AES+CBC的解密函数。

function aesDecrypt(dataEncoded, passphrase){
    var key, iv, hKey, hIV, dataDecRes;
    // make key & iv
    key = CryptoJS.MD5(passphrase).toString();
    iv = key.substr(0, 16);
    hKey = CryptoJS.enc.Hex.parse(key);
    hIV = CryptoJS.enc.Hex.parse(iv);
    // decrypt
    dataDecRes = CryptoJS.AES.decrypt(
        dataEncoded,
        hKey,
        {
            iv: hIV,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return dataDecRes;
}

现在福哥使用aesDecrypt这个函数来解密刚刚加密后的数据。加密的数据包括十进制格式的,还有十六进制(Hex)格式的。

我们先来解密十进制格式的,十进制格式的可以直接解密。

// decrypt
console.log("====== decrypt ======");
dataDecRes = aesDecrypt(dataEncStr, passphrase);
dataDecStr = dataDecRes.toString(CryptoJS.enc.Utf8);
console.log("data decoded result:", dataDecRes);
console.log("data decoded string:", dataDecStr);

接着我们来解密十六进制(Hex)格式的,这里需要先把它转换成十进制格式的,然后再来解密。

// decrypt by ciphertext
console.log("====== decrypt ciphertext ======");
dataEncStr = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(dataEncCipherTextStr));
console.log("data encoded string:", dataEncStr);
dataDecRes = aesDecrypt(dataEncStr, passphrase);
dataDecStr = dataDecRes.toString(CryptoJS.enc.Utf8);
console.log("data decoded result:", dataDecRes);
console.log("data decoded string:", dataDecStr);

效果

这是执行结果!大家的环境下如果结果不一样,请仔细检查~

home/topic/2023/0818/15/f55a1bbf7bfa8c82e6273e612846093e.png