如何实现crypto-js加密功能跨机器独立运行
问题描述
我是crypto-js库(以及Node.js整体)的新手,目前将其用于UI测试自动化场景,通过服务账号完成登录操作,编写的工具类如下:
import credsJson from './creds.json'; import * as crypto from 'crypto-js'; import passKey from './passKey.json'; export class Utility { getCredentials(): Credentials{ let creds = new Credentials(); creds.userName = credsJson.userName; let encoded = credsJson.password; creds.password = crypto.AES.decrypt(encoded, passKey.passKey).toString(crypto.enc.Utf8); return creds; } encryptPassword(){ var encrypted = crypto.AES.encrypt(credsJson.password, passKey.passKey).toString(); } } export class Credentials { userName: string; password: string; }
我在Debug模式下的测试方法中引用该类,对creds.json中存储的密码进行加密,获取新生成的加密密码后替换原有密文,对应的测试代码如下:
test.describe('ChangePassword', () => { test('test encryption', async () => { var pass = new Utility(); pass.encryptPassword();
目前代码运行状态正常,存在如下技术疑问:
- 是否有方案可以让该加密逻辑实现机器无关性?
- 当前使用的服务账号、明文密码、密钥均完全一致,但如果要在3台不同机器上执行代码,必须分别在每台机器上单独执行一次加密操作,因为不同机器生成的加密密文结果均不相同。
- 请问是否有方法可以规避该问题,或是该现象本身就是crypto-js的正常运行表现?
解答
这个现象是crypto-js AES加密的正常表现,和运行机器没有任何关系。
crypto-js默认的AES.encrypt方法采用CBC加密模式,每次调用时会自动生成随机的16字节初始化向量(IV)。加密安全设计规范里,CBC模式的IV本身就要求是随机不可预测的,只要IV不同,哪怕明文、加密密钥完全一致,最终输出的密文也必然不同——这个设计的目的就是避免相同明文始终生成相同密文,降低被密码分析破解的风险。
你完全不需要在每台机器单独执行加密操作:只要密文是通过对应密钥合法加密生成的,在任意机器上使用相同密钥调用解密方法,都能正确还原出明文,跨机器解密失败和机器差异无关,优先检查自己的加解密参数、文件读取逻辑是否有问题。
如果你是测试场景,确实需要让相同明文+密钥始终输出固定密文(注意:该方案会降低加密安全性,禁止在生产高安全场景使用),可以手动指定固定IV,统一所有环境的加解密参数即可,修改后的代码参考如下:
import * as crypto from 'crypto-js'; // 所有环境统一使用固定IV,长度必须为16字节,可自行设置固定值 const FIXED_IV = crypto.enc.Utf8.parse('1234567890abcdef'); // 提前将密钥解析为WordArray格式,避免默认解析规则差异 const FIXED_KEY = crypto.enc.Utf8.parse(passKey.passKey); export class Utility { getCredentials(): Credentials{ let creds = new Credentials(); creds.userName = credsJson.userName; let encoded = credsJson.password; // 解密时同步传入相同的IV、加密模式、填充规则 creds.password = crypto.AES.decrypt(encoded, FIXED_KEY, { iv: FIXED_IV, mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7 }).toString(crypto.enc.Utf8); return creds; } encryptPassword(){ var encrypted = crypto.AES.encrypt(credsJson.password, FIXED_KEY, { iv: FIXED_IV, mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7 }).toString(); // 原方法没有返回值,要获取加密结果必须加return return encrypted; } }
补充两个你现有代码的小问题:
- 原
encryptPassword方法没有返回值,debug时如果要拿到生成的密文,必须补充return逻辑 - 如果使用默认随机IV的模式,不需要修改解密逻辑,crypto-js会自动从密文格式里解析出对应的IV,直接解密即可
内容的提问来源于stack exchange,提问作者JD2775
相关产品推荐
相关产品推荐

