【发布时间】:2012-05-14 21:02:12
【问题描述】:
我正在使用 Hibernate/Java 将实体持久保存到数据库中。该实体有一个 password 字段,它是一个 String。在我的应用程序中注册用户时,我使用 SHA-1 对密码进行哈希处理(我承认这有点弱)。这会产生一个 byte[] ,然后我将其转换为 String 使用
new String(byte[] arr);
每当我想登录用户时,我只需从数据库中检索散列密码(作为 String)并将其与登录时输入密码的摘要进行比较
hashedPasswordFromDatabase.equals(SHA1_HASH(inputPassword));
这在我的开发系统(Windows 7、JDK 1.6.0_23 / JDK 1.7、MySQL 5.5、Tomcat 6.0.26)上完美运行,但在我们的服务器上部署后(在 Linux 上运行 JDK 1.6 ),即使密码相同,equals 方法也永远不会计算为 TRUE。我快速设置了一个新的开发系统(Ubuntu 12.04、MySQL 5.5、JDK 1.7.0_03、Tomcat 7.0.22),但它也不能在那里工作。
我知道 String 类的 Java API 文档中所述的可能的编码问题,并且在 SO 的几个地方也有说明。我尝试了该论坛上建议的几种编码(例如 Base64、Latin-1),但最终得到了 UnsupportedEncodingException。我想我最好避免字符串转换。那么如何设计我的数据库,以便 Hibernate 生成的实体类为 password 字段提供 byte[] 而不是 String?
【问题讨论】:
-
+1,非常好的问题。顺便说一句,这不是您问题的答案,我很幸运地使用了一些进出数据库的 Commons Base64 实用程序。
-
为什么要存储代表数字的字符串而不是存储数字本身?
-
不要使用一轮散列来保护密码。使用 PBKDF2 或 bcrypt 之类的方法进行 10 万轮 --- 即使 100k 也不是不合理的。直接存储固定长度的
byte[]对于更多数据库来说应该很容易,但您始终可以从字节数组创建BigInteger并将其存储为数字类型。 -
@erickson 是的,不错。我打算在解决这个问题后升级密码保护的强度(刮掉 SHA-1、加盐、多重哈希等)。
-
数据库中的数据类型是什么?
标签: java string hibernate encoding sha1