利用 SJCL、CryptoJS 和/或 WebCrypto 的现有答案不一定是错误的,但它们并不像您最初怀疑的那样安全。通常你想使用 libsodium。首先我将解释为什么,然后解释如何。
为什么不是 SJCL、CryptoJS、WebCrypto 等?
简短回答:为了让您的加密真正安全,这些库希望您做出太多选择,例如分组密码模式(CBC、CTR、GCM;如果您无法分辨我刚刚列出的三个中的哪一个是安全的使用和在什么样的约束,你不应该有这种选择的负担在所有)。
除非你的职位是密码学工程师,否则你安全地实施它的可能性很大。
为什么要避免 CryptoJS?
CryptoJS 提供了一些构建块,并希望您知道如何安全地使用它们。它甚至默认为 CBC 模式(已存档)。
为什么 CBC 模式不好?
阅读这篇关于 AES-CBC 漏洞的文章。
为什么要避免 WebCrypto?
WebCrypto 是一个便餐标准,由委员会设计,用于与密码工程正交的目的。具体来说,WebCrypto 旨在取代 Flash,而不是提供安全性。
为什么要避免 SJCL?
SJCL 的公共 API 和文档要求用户使用人类记住的密码加密数据。这在现实世界中很少(如果有的话)您想要做的。
另外:它的默认 PBKDF2 轮数大约是您希望的 86 倍。AES-128-CCM 可能没问题。
在上述三个选项中,SJCL 最不可能以眼泪收场。但是有更好的选择。
为什么 Libsodium 更好?
您无需在密码模式菜单、散列函数和其他不必要的选项之间进行选择。您永远不会冒着搞砸参数和从协议中删除所有安全性的风险。
相反,libsodium只是为您提供针对最大安全性和简约 API 进行调整的简单选项。
crypto_box()
/crypto_box_open()
提供经过身份验证的公钥加密。
- 有问题的算法结合了 X25519(ECDH over Curve25519)和 XSalsa20-Poly1305,但你不需要知道(甚至关心)它来安全地使用它
crypto_secretbox()
/crypto_secretbox_open()
提供共享密钥认证加密。
- 有问题的算法是 XSalsa20-Poly1305,但你不需要知道/关心
此外,libsodium绑定了数十种流行的编程语言,因此当尝试与另一个编程堆栈进行互操作时,libsodium 很可能会正常工作。此外,libsodium 在不牺牲安全性的情况下往往非常快。
如何在 JavaScript 中使用 Libsodium?
首先,你需要决定一件事:
- 您是否只想加密/解密数据(并且可能仍然以某种方式安全地在数据库查询中使用明文)而不担心细节?或者...
- 您需要实现特定的协议吗?
如果您选择了第一个选项,请获取CipherSweet.js。
该文档可在线获取。EncryptedField
对于大多数用例来说已经足够了,但是如果您有很多不同的字段要加密,则EncryptedRow
和EncryptedMultiRows
API 可能会更容易。
使用 CipherSweet,您甚至不需要知道 nonce/IV 是什么就可以安全地使用它。
此外,这种处理int
/float
加密不会通过密文大小泄露有关内容的事实。
否则,您将需要钠加,它是各种 libsodium 包装器的用户友好前端。钠加允许您编写易于审计和推理的高性能、异步、跨平台代码。
要安装钠加,只需运行...
npm install sodium-plus
目前没有用于浏览器支持的公共 CDN。这将很快改变。但是,如果需要,您可以sodium-plus.min.js
从最新的 Github 版本中获取。
const { SodiumPlus } = require('sodium-plus');
let sodium;
(async function () {
if (!sodium) sodium = await SodiumPlus.auto();
let plaintext = 'Your message goes here';
let key = await sodium.crypto_secretbox_keygen();
let nonce = await sodium.randombytes_buf(24);
let ciphertext = await sodium.crypto_secretbox(
plaintext,
nonce,
key
);
console.log(ciphertext.toString('hex'));
let decrypted = await sodium.crypto_secretbox_open(
ciphertext,
nonce,
key
);
console.log(decrypted.toString());
})();
可以在 Github 上找到关于 salt -plus的文档。
如果您需要分步教程,这篇 dev.to 文章可以满足您的需求。