我将用户密码以sha1散列的形式存储在数据库中。
不幸的是,我得到了奇怪的答案。
我将字符串存储为:
MessageDigest cript = MessageDigest.getInstance("SHA-1");
cript.reset();
cript.update(userPass.getBytes("utf8"));
this.password = new String(cript.digest());
我想要这样的东西-->
aff --> "0c05aa56405c447e6678b7f3127febde5c3a9238“
而不是
aff -->�V@\D~fx����:�8
发布于 2010-12-10 00:51:24
之所以会发生这种情况,是因为cript.digest()返回一个字节数组,您正试图将其打印为字符串。您希望将其转换为可打印的十六进制字符串。
简单的解决方案:使用Apache的commons-codec library
String password = new String(Hex.encodeHex(cript.digest()),
CharSet.forName("UTF-8"));
发布于 2011-07-15 20:16:53
使用apache公共编解码库:
DigestUtils.sha1Hex("aff")
结果是0c05aa56405c447e6678b7f3127febde5c3a9238
就是这样:)
发布于 2010-12-10 00:57:56
哈希算法的一次迭代是不安全的。太快了。您需要通过多次迭代散列来执行键强化。
此外,您没有对密码进行加盐处理。这为预先计算的字典创建了一个漏洞,比如“彩虹表”。
您可以使用Java运行时中内置的代码,而不是尝试使用自己的代码(或使用一些粗略的第三方臃肿软件)来正确完成此操作。详情请参见this answer。
一旦您正确地对密码进行了哈希处理,您就会得到一个byte[]
。将其转换为十六进制String
的一种简单方法是使用BigInteger
类:
String passwordHash = new BigInteger(1, cript.digest()).toString(16);
如果您希望确保字符串始终包含40个字符,则可能需要在左侧填充一些零(可以使用String.format()
完成此操作)。
https://stackoverflow.com/questions/4400774
复制相似问题