jon*_*ono 75 javascript hash sha256 sha2
我正在为一个论坛写一个登录,并且需要在将它发送到服务器之前在javascript中对密码客户端进行散列.我无法确定哪些SHA-256实现我可以信任.我期待每个人都使用某种权威脚本,但我发现大量不同的项目都有自己的实现.
我意识到使用其他人的加密始终是信仰的飞跃,除非你有资格自己审查它,并且没有"值得信赖"的普遍定义,但这似乎是一种常见且重要的东西,应该有某种形式关于使用什么的共识.我只是天真吗?
编辑,因为它在评论中出现了很多:是的,我们在服务器端再次执行更严格的哈希.客户端散列不是我们在数据库中保存的最终结果.客户端散列是因为人类客户端请求它.他们没有给出具体原因,可能他们只是喜欢矫枉过正.
tyl*_*erl 94
在斯坦福JS加密库包含SHA-256的实现.虽然JS中的加密并不像其他实现平台那样经过良好的审查,但这个问题至少部分是由Dan Boneh开发的,并且在某种程度上由Dan Boneh赞助,他是密码学中公认且值得信赖的名称. ,并且意味着该项目对实际知道他在做什么的人有一些疏忽.该项目也得到了NSF的支持.
但值得指出的是......
如果你在提交密码之前对客户端密码进行哈希处理,那么哈希就是密码,而原始密码就变得无关紧要了.攻击者只需要拦截散列以模仿用户,如果该散列未经修改地存储在服务器上,则服务器以纯文本形式存储真密码(散列).
因此,您的安全性现在变得更糟,因为您决定将自己的改进添加到以前的可信方案中.
Vit*_*ich 28
在https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest上,我发现这个使用内部js模块的代码片段:
async function sha256(message) {
// encode as UTF-8
const msgBuffer = new TextEncoder('utf-8').encode(message);
// hash the message
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
// convert ArrayBuffer to Array
const hashArray = Array.from(new Uint8Array(hashBuffer));
// convert bytes to hex string
const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
return hashHex;
}
Run Code Online (Sandbox Code Playgroud)
请注意,crypto.subtle
仅在您可以使用https
或localhost
- 例如您的本地开发时python3 -m http.server
需要将此行添加到您的/etc/hosts
:
0.0.0.0 localhost
重启 - 你可以打开localhost:8000
工作crypto.subtle
.
bri*_*out 16
Forge的SHA-256实现快速可靠.
要在几个SHA-256 JavaScript实现上运行测试,请访问http://brillout.github.io/test-javascript-hash-implementations/.
我的机器上的结果表明伪造是最快的实现,也比接受的答案中提到的斯坦福Javascript加密库(sjcl)快得多.
Forge大256 KB,但提取SHA-256相关代码会将大小减小到4.5 KB,请参阅https://github.com/brillout/forge-sha256
Rei*_*ica 10
不,没有办法使用浏览器JavaScript来提高密码安全性.我强烈建议你阅读这篇文章.在你的情况下,最大的问题是鸡蛋问题:
提供Javascript加密技术的"鸡蛋问题"是什么?
如果您不信任网络提供密码,或者更糟糕的是,不信任服务器不保留用户机密,则您不能相信它们提供安全代码.在你引入加密之前嗅探密码或阅读日记的同一攻击者只是劫持了加密代码.
[...]
为什么我不能使用TLS/SSL来提供Javascript加密代码?
您可以.它比听起来更难,但你可以安全地使用SSL将Javascript加密传输到浏览器.问题是,通过SSL建立安全通道后,您不再需要Javascript加密; 你有"真正的"密码学.
这导致了这个:
在Javascript中运行加密代码的问题在于,实际上加密所依赖的任何函数都可以被用于构建托管页面的任何内容静默地覆盖.加密安全性可以在过程的早期(通过生成伪随机数,或通过篡改算法使用的常量和参数)或稍后(通过将关键材料激活回攻击者)或在最可能的场景中撤消.---完全绕过加密.
任何Javascript代码都没有可靠的方法来验证其执行环境.Javascript加密代码不能问,"我真的在处理一个随机数生成器,还是一些攻击者提供的传真?" 它当然不能断言"除了我作者所赞同的方式之外,没有人被允许对这个加密秘密做任何事情".这些是通常在使用加密的其他环境中提供的两个属性,在Javascript中它们是不可能的.
基本上问题是这样的:
或者,
注意:此外,SHA-256不适用于此,因为它非常容易强制使用未加密的非迭代密码.如果您决定这样做,请查找bcrypt,scrypt或PBKDF2的实现.
cob*_*lla 10
我发现这个实现非常容易使用.还有一个慷慨的BSD风格许可证:
jsSHA:https://github.com/Caligatio/jsSHA
我需要一种快速方法来获取SHA-256哈希的十六进制字符串表示.它只花了3行:
var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");
Run Code Online (Sandbox Code Playgroud)
对于那些感兴趣的人,这是用于创建SHA-256哈希的代码sjcl
:
import sjcl from 'sjcl'
const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)
Run Code Online (Sandbox Code Playgroud)