为什么每次浏览器加载时CryptoJS都会产生不同的价值

时间:2017-11-02 19:12:19

标签: javascript cryptojs

以下代码通过脚本标记在网页上运行。每次我加载页面或在浏览器控制台中运行代码时 - 我都会得到不同的价值......

var key = 'key-123:456';
var uid = 1234567890;
var encrypted = CryptoJS.AES.encrypt(id, key);
encrypted.toString();

无论我加载页面或在控制台中运行代码多少次,如何为“单个ID”设置单个“加密值”?

1 个答案:

答案 0 :(得分:1)

AES是一个"块"密码,这意味着它在从明文到密文的固定长度块上确定性地运行(反之亦然)。但是,使用" mode of operation"是典型的(通常是首选的)这会给加密过程增加非确定性。例如,CBC模式(默认情况下CryptoJS使用)在加密之前对带有明文的随机初始化向量进行异或(相应地,在解密之后):

diagram of CBC mode showing first plaintext block XORed with initialization vector (IV)

这是非常受欢迎的,因为否则窃听者可以检测到重复的块,这可能允许攻击者最终了解正在传达的内容 - 撤消整个加密点。

然而,听起来你希望你的加密有这个特定的弱点,这告诉我,你可能根本不想加密。相反,您可能需要哈希,这是一种确定性的单向转换。 (CryptoJS supports several hashes.)使用哈希,给定的输入A将始终哈希到相同的哈希值H,因此您可以比较Hash(A) == Hash(B)以查看是否A == B 。 (这不是完美的比较,因为哈希具有无限的输入空间和有限的输出空间,但是哈希是故意设计的,因此它是very, very difficult to find two inputs that produce the same output。)这就是网站安全存储密码的方式:服务存储Hash(password)而不是password本身,然后当用户提交密码条目时,网站会比较Hash(entry)Hash(password)以查看条目是否正确。

var hash = CryptoJS.SHA3(message);

但是,如果您确实需要将转换后的值反转回明文而不仅仅将其与另一个散列值进行比较,那么您确实需要加密。在这种情况下,您可以使用加密性较差的ECB模式,该模式具有上述缺点。在CryptoJS中,您可以通过提供具有mode属性的选项对象来执行此操作:

CryptoJS.AES.encrypt(msg, key, { mode: CryptoJS.mode.ECB });