基本上我的目标是使用日期作为salt密钥来加密我的密码。我使用SHA-512来做这件事。当我加密密码时,我会捕获今天的日期,比如varDate,这是java.util.Date
类型,然后进行加密。如果我通过执行varDate.toString()
输出它,我会看到Thu Jul 18 17:37:27 SGT 2013
。然后将varDate
存储到DB中。
当解密时,我将提供密码并从DB中查询varDate
,它也是java.util.Date
类型,加密并进行比较。有趣的是,这总是会失败,因为加密的值永远不会匹配。我发现当我输出来自DB的varDate
时,我的格式为2013-07-18 17:37:27.0
。
我是如此惊讶,如此好奇和挣扎为什么会发生这种情况?我想知道这是否是导致加密失败的根本原因?
这是为了说明代码如何在我的哈希算法上工作。我有一个函数接受密码作为字符串,盐密钥作为字符串,然后对密码进行散列,如下所示:
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.reset();
md.update(saltKey.getBytes());
md.digest(password.getBytes("UTF-8"));
我的实验表明,通过传入Date对象,我无法获得一致的结果。但是如果我将它重新格式化为字符串,那么只有我才能获得一致的结果。在我看来,日期对象不是一个好的盐键候选者。
答案 0 :(得分:2)
您不应该使用Date.toString()
。它的输出取决于日期的实际具体类型,可能是java.util.Date
(您的第一种情况,可能是),java.sql.Timestamp
(您的第二种情况,可能是)或java.sql.Date
。它还取决于当前时区。
我的建议是忘记完全使用盐的日期。使用SecureRandom生成随机盐,并将此盐存储在数据库中。
如果你真的坚持使用Date,那么使用可靠的机制将其转换为String,例如具有固定模式的SimpleDateFormat
和UTC时区。
答案 1 :(得分:1)
始终格式化日期,使用显式格式将日期/时间类型转换为字符串。这样你就可以得到你想要的东西,而且你不会依赖系统默认格式(可以由用户更改和重新配置)。