RN—AES的使用

1、安装

npm install crypto-js
npm install --save-dev @types/crypto-js

2、封装

import CryptoJS from "crypto-js"

export class AESUtils {
    defIv: string;
    constructor(){
        this.defIv = this.generateIV();
    }

    /**
     * 生成随机的AES密钥
     * @param bits - 密钥位数(128/192/256),默认为256
     * @returns {string} 十六进制字符串格式的密钥
     */
     generateAESKey(bits = 256) : string { 
        const byteLength = bits * 8;
        return CryptoJS.lib.WordArray.random(byteLength).toString();
    }

    /**
     * 生成随机的初始化向量(IV)
     * @returns {string} 十六进制字符串格式的IV
     */
    generateIV() : string{
        //AES块大小是128位(16字节)
        return CryptoJS.lib.WordArray.random(16).toString();
    }

    /**
     * AES加密
     * @param data 需要加密的对象或字符串
     * @param aesKey AES密钥
     * @param iv 初始化向量
     * @returns base64格式的加密字符串
     */
    encrypt(data: any,aesKey: string,iv: string = this.defIv) : string {
        try{
            const dataString = typeof data === 'object' ? JSON.stringify(data) : String(data);
            const keyWordArray = CryptoJS.enc.Hex.parse(aesKey);
            const ivWordArry = CryptoJS.enc.Hex.parse(this.defIv);

            //执行aes加密(cbc模式)
            const encrypted = CryptoJS.AES.encrypt(dataString,keyWordArray,{
                iv: ivWordArry,
                mode: CryptoJS.mode.CBC,

                //PKCS#7填充规则:缺多少字节,就填充多少个值为"缺少字节数"的字节
                padding: CryptoJS.pad.Pkcs7
            });
            
            return encrypted.toString();
        }catch(error){
            console.error("加密失败",error)
            throw new Error('加密失败:${error.message}')
        }
    }

    /**
     * aes解密
     * @param cipherText 需要解密的字符串
     * @param aesKey aes密钥
     * @param iv 初始化向量
     * @returns utf-8格式的字符串
     */
    decrypt(cipherText: string,aesKey: string,iv: string = this.defIv) : string {
        try{
            const keyWordArray = CryptoJS.enc.Hex.parse(aesKey);
            const ivWordArry = CryptoJS.enc.Hex.parse(this.defIv);

            //执行aes加密(cbc模式)
            const decrypted = CryptoJS.AES.decrypt(cipherText,keyWordArray,{
                iv: ivWordArry,
                mode: CryptoJS.mode.CBC,

                //PKCS#7填充规则:缺多少字节,就填充多少个值为"缺少字节数"的字节
                padding: CryptoJS.pad.Pkcs7
            });
            
            return decrypted.toString(CryptoJS.enc.Utf8);
        }catch(error){
            console.error("解密失败",error)
            throw new Error('解密失败:${error.message}')
        }
    }
}

3、单元测试代码

import { AESUtils } from "../rn/utils/AESUtils";


describe('',() => {
    test("测试aes的加解密", () => {
        const aesUtils = new AESUtils();
        const srcString = "乔乔";

        //获取aeskey
        const aesKey = aesUtils.generateAESKey();

        //加密
        const encryptString = aesUtils.encrypt(srcString,aesKey);
        //解密
        const decryptString = aesUtils.decrypt(encryptString,aesKey);

        expect(srcString).toBe(decryptString);

    })
});