Javascript 验证解密字符串
我正在使用Node.js加密库使用AES-256-ctr加密较大的文件。我现在遇到的一个问题是验证解密是否成功。目前,如果我使用了错误的密码,我无法知道解密失败,直到我查看文本并意识到它不可读,但这使得以编程方式检查和请求密码重试变得困难 到目前为止,我从我的研究中收集到了什么(如果我错了,请纠正我):Javascript 验证解密字符串,javascript,encryption,cryptography,Javascript,Encryption,Cryptography,我正在使用Node.js加密库使用AES-256-ctr加密较大的文件。我现在遇到的一个问题是验证解密是否成功。目前,如果我使用了错误的密码,我无法知道解密失败,直到我查看文本并意识到它不可读,但这使得以编程方式检查和请求密码重试变得困难 到目前为止,我从我的研究中收集到了什么(如果我错了,请纠正我): 我可以使用HMAC来验证解密消息的完整性 我应该始终在加密后运行HMAC函数,因为在加密数据之前对任何内容进行哈希,而不加密哈希本身会破坏加密的目的 加密和MAC不要使用相同的密钥 我的问题
- 我可以使用HMAC来验证解密消息的完整性
- 我应该始终在加密后运行HMAC函数,因为在加密数据之前对任何内容进行哈希,而不加密哈希本身会破坏加密的目的
- 加密和MAC不要使用相同的密钥
我不知道这是一个愚蠢的问题,还是我只是没有寻找正确的东西,但是一些类似的问题只是说使用aes gcm来避免担心这个问题。我很好奇怎么做。您可能不想在消息前面加一个字符串。这是因为攻击者可以篡改初始字符串之外的消息,而您仍然无法检测到它。因为CTR模式使用带有密钥流的XOR进行加密,所以这很简单 您需要做两件事中的一件:使用AEAD进行加密,如AES-GCM或ChaCha20-Poly1305,或使用CTR模式对加密数据使用HMAC。请注意,如果这样做,则决不能重复使用加密的密钥对,否则将失去所有安全性 最简单、最简单的方法是使用AES-GCM。您可以以适当的方式生成单个加密安全密钥。然后,从系统CSPRNG生成一个随机的256位salt。然后执行此操作(
|
是浓缩):
这用于生成一个加密密钥,即IV(需要将其截断为12个字节)。加密数据,并发出32字节的salt和加密消息
这样,只要您总是为每个加密选择一个随机的salt,那么您是否使用相同的初始密钥并不重要,因为您实际上永远不会重复使用密钥对
如果这些文件太大,以至于您无法等着检查整个加密是否正确,那么再添加一个32字节的值:
check-value = HMAC-SHA-256(PRK, "check value" || 0x01)
然后,发出salt、检查值和使用AES-GCM加密的数据。要验证密码,请检查检查值是否相同,如果不相同,则为错误。如果ChaCha20-Poly1305更适合您的环境(ARM系统或其他没有AES加速的系统),那么所有这些方法也可以通过ChaCha20-Poly1305实现
额外的0x01字节严格来说是不必要的,但使用它意味着您使用的是HKDF,这意味着您可以说您使用的是一种备受尊重的标准方法。使用node.js加密库是否正确?我相信您提到的一些技术在某种程度上已经融入了函数中,比如“setAuthTag()”,但我可能错了。我对你上一次的评论很感兴趣,不过我只是想检查一个连接到文件末尾的32字节的值。是的,所有这些看起来都很好。您正在使用scrypt或CSPRNG生成所有内容,因此您应该是优秀的。
check-value = HMAC-SHA-256(PRK, "check value" || 0x01)