使用CryptoJS调用createCipheriv时出现TypeError错误求助
问题:使用CryptoJS创建密码器时出现Uncaught TypeError错误
我尝试用CryptoJS创建密码器时一直碰到这个错误:Uncaught TypeError: Cannot read properties of undefined (reading 'call')。IV能正常生成,但创建密码器时程序崩溃。
我的代码
const crypto = require("crypto"); const algorithm = "aes-256-ctr"; const secretKey = "blep"; const encrypt = (text) => { const iv = crypto.randomBytes(16); // 这里触发了上述错误 const cipher = crypto.createCipheriv(algorithm, secretKey, iv); const encrypted = Buffer.concat([cipher.update(text), cipher.final()]); return { iv: iv.toString("hex"), content: encrypted.toString("hex"), }; }; const decrypt = (hash) => { const decipher = crypto.createDecipheriv( algorithm, secretKey, Buffer.from(hash.iv, "hex") ); const decrpyted = Buffer.concat([ decipher.update(Buffer.from(hash.content, "hex")), decipher.final(), ]); return decrpyted.toString(); }; module.exports = { encrypt, decrypt, };
完整错误信息
index.js:7 Uncaught TypeError: Cannot read properties of undefined (reading 'call') at StreamCipher.CipherBase (index.js:7:1) at new StreamCipher (streamCipher.js:7:1) at Object.createCipheriv (encrypter.js:97:1) at Object.createCipheriv (browser.js:45:1) at encrypt (crypto.js:9:1) at ./src/services/service.js (service.js:5:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./src/pages/page.js (page.js:12:1)
解决方案
核心问题:混淆了Node.js内置crypto模块和CryptoJS库
你代码里用的require("crypto")是Node.js的后端加密模块,但错误栈显示代码在浏览器环境(browser.js)运行,且你提到的是CryptoJS——这说明你搞混了两个完全不同的加密工具:
- Node.js的
crypto模块仅适用于后端,直接在浏览器环境运行会出现兼容性问题 - CryptoJS是专为浏览器设计的加密库,API和Node.js
crypto完全不兼容
修正步骤:改用CryptoJS的正确API
- 先安装CryptoJS:
npm install crypto-js - 修改代码为CryptoJS的标准写法:
const CryptoJS = require("crypto-js"); const secretKey = CryptoJS.enc.Utf8.parse("blep"); // 转换为CryptoJS所需的WordArray格式 const ivLength = 16; // AES-CTR模式标准IV长度 const encrypt = (text) => { // 生成随机IV const iv = CryptoJS.lib.WordArray.random(ivLength); // 使用CTR模式加密 const encrypted = CryptoJS.AES.encrypt(text, secretKey, { iv: iv, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding // CTR模式无需填充 }); return { iv: iv.toString(CryptoJS.enc.Hex), content: encrypted.ciphertext.toString(CryptoJS.enc.Hex) }; }; const decrypt = (hash) => { // 将存储的IV和密文转换为WordArray const iv = CryptoJS.enc.Hex.parse(hash.iv); const ciphertext = CryptoJS.enc.Hex.parse(hash.content); // 构建CipherParams对象供解密使用 const cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext }); const decrypted = CryptoJS.AES.decrypt(cipherParams, secretKey, { iv: iv, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding }); return decrypted.toString(CryptoJS.enc.Utf8); }; module.exports = { encrypt, decrypt };
额外注意事项
- AES-256要求密钥长度为32字节,你当前使用的"blep"仅4字节,CryptoJS会自动补全,但生产环境建议使用32位随机字符串作为密钥
- 加密解密的模式、填充方式、编码格式必须完全一致,否则会导致解密失败
内容的提问来源于stack exchange,提问作者Pieter Burger
相关产品推荐
相关产品推荐

