【问题标题】:Storing a hash as byte array with JPA使用 JPA 将哈希存储为字节数组
【发布时间】:2011-04-18 19:27:03
【问题描述】:

我的User 实体类包含密码哈希字段,这是一个固定长度的字节数组(32,因为它是 SHA-256 哈希)。

@Entity
public class User {
    @Column(nullable=false)
    private byte[] passwordHash;
    ...
}

如您所见,我没有用任何特殊的注释对其进行注释,只是一个 NOT NULL。

这可行,但它会执行吗?我的架构是由 Hibernate 生成的,但我不知道它究竟生成了什么(我目前正在使用内存中的 HSQL 数据库)。

我担心,因为它不知道它是一个固定长度的数组(Column 注释的length 字段仅适用于字符串),它会将此哈希存储在一个 BLOB 字段中作为指针添加到记录中(如果我正确理解数据库的工作原理)。

这是真的吗,我该如何改变?我是否应该将哈希编码为字符串,使用 base64 或十六进制,接受它对性能/正确性的小影响?

【问题讨论】:

  • 为什么不用实际的目标数据库试试,看看它会生成什么?
  • @skaffman:我已将数据库更改为 MySQL,它会生成一个 TINYBLOB 列
  • 虽然我认为这真的无关紧要。我永远不会通过密码哈希进行索引,我一次只需要读取一条记录。不过,出于学术目的,我仍然有兴趣让它变得完美。

标签: database hibernate jpa hash blob


【解决方案1】:

tinyblob 是个不错的选择 (mysql types reference),但我所有的应用程序都可以正常使用字符串。 如果您真的关心毫秒,请在分析器中尝试这两个版本,看看哪个最有效。我首选的分析器是 netbeans 中包含的。

【讨论】:

    【解决方案2】:

    据我所知,SHA-256 哈希始终只是可打印字符(如果不是,则将其编码为 base64),因此解决方案是您可以将其存储为字符串,然后使用 length 字段Column注解。

    那么你就有了固定的长度,而且性能毫无疑问。

    【讨论】:

    • 不,我已经看到了输出,它实际上主要由不可打印的字符组成(或者根本不是字符数据)。我当然可以使用 base64 或 hex 对其进行编码,但如果我能以纯二进制形式存储它,那就太好了。
    【解决方案3】:

    我很担心,因为它不知道它是一个固定长度的数组(Column 注释的长度字段仅适用于字符串),(...)

    如果您指定列长度,Hibernate 将使用此信息来确定要生成的 SQL 列类型(TINYBLOBBLOBMEDIUMBLOBLONGBLOB)。

    我需要的是 BINARY(32)

    你试过了吗?

    @Column(columnDefinition="BINARY(32) NOT NULL")
    private byte[] passwordHash;
    

    【讨论】:

      【解决方案4】:

      它可能效率不高,但我建议您使用 String 作为存储类型,并根据需要使用 getter 和 setter 方法进行转换。这允许 JPA 在不同数据库之间的最大可移植性。

      我使用与日期/时间类似的技术,通过存储表示自 UTC 纪元以来的时间的长整数,这使我可以避免时区问题(时区信息在所有数据库的数据库日期中不可移植)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-14
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2020-07-27
        • 2012-10-29
        • 1970-01-01
        相关资源
        最近更新 更多