CryptoJS 是前端最好用的加密框架,然而这个加密框架在处理 AES 加密时有点小心机你知道吗?

0x1、最为常见的AES加密方式,使用固定长度key

encrypt: function (cipher, message, key, cfg) {
    * @param {Cipher} cipher The cipher algorithm to use.
    * @param {WordArray|string} message The message to encrypt.
    * @param {WordArray} key The key.
    * @param {Object} cfg (Optional) The configuration options to use for this operation.
    * @return {CipherParams} A cipher params object.

    cfg = this.cfg.extend(cfg);
    var encryptor = cipher.createEncryptor(key, cfg);
    var ciphertext = encryptor.finalize(message);
    var cipherCfg = encryptor.cfg;
    return CipherParams.create({
        ciphertext: ciphertext,
        key: key,
        iv: cipherCfg.iv,
        algorithm: cipher,
        mode: cipherCfg.mode,
        padding: cipherCfg.padding,
        blockSize: cipher.blockSize,
        formatter: cfg.format
    });
}

0x2、较少见的AES加密方式,可以使用任意长度key,返回结果次次不同

encrypt: function (cipher, message, password, cfg) {
    * @param {Cipher} cipher The cipher algorithm to use.
    * @param {WordArray|string} message The message to encrypt.
    * @param {string} password The password.
    * @param {Object} cfg (Optional) The configuration options to use for this operation.
    * @return {CipherParams} A cipher params object.

    cfg = this.cfg.extend(cfg);
    var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
    cfg.iv = derivedParams.iv;
    var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
    ciphertext.mixIn(derivedParams);
    return ciphertext;
}

0x3、总结

第一种方式传入的第三个参数key类型为WordArray , 这是由我们最常见的 CryptoJS.enc.Utf8.parse() 或 CryptoJS.enc.Latin1.parse() 处理过后的类型,这个WordArray传入后会直接用作Key,所以:相同key,相同内容,每次加密结果均相同
第二种方式传入的第三个参数password类型为string , 它会被 CryptoJS.lib.PasswordBasedCipher 处理,并用 cfg.kdf 生成一个新的 WordArray,这个生成出来的东西才是实际的 key。这个生成出来的东西是具有随机性的,所以:相同password,相同内容,每次加密结果均不相同
如果觉得我的文章对你有用,请随意赞赏