【问题标题】:before and after using a cryptographic hash function使用加密哈希函数之前和之后
【发布时间】:2013-03-07 15:10:18
【问题描述】:

在查看了用于生成 Java MD5 和 SHA* 哈希的多个在线参考之后,我注意到纯文本(文件字符串)在被馈送到 Digest 对象以生成哈希之前和之后都经过了一定的准备。 具体来说,首先将数据转换为字节数组,然后馈入摘要,然后将输出哈希转换为十六进制流。 为什么所有这些字节和十六进制转换?

PS:我想答案与 Java 和 Digest 对象如何开展业务有关,我提出这个问题的动机是了解这种行为,并可能获得对一些解释这一点的文档/文献的引用深入。

丹克!

【问题讨论】:

    标签: java hex bytearray checksum cryptographic-hash-function


    【解决方案1】:

    这有两个部分:

    1. 为什么我们要在消化之前将 String 转换为字节数组?
    2. 为什么要将摘要转换为十六进制?

    第一个答案是摘要适用于字节数组。他们对字符串、数字或任何其他数据类型一无所知。只是字节。因此,我们获取一个String 对象并使用某种形式的文本编码(例如 UTF-8)将其转换为字节数组。

    请注意,编码很重要:我可以用 UTF-8、UTF-16、US-ASCII 或任何数量的其他编码对字符串“hello world”进行编码。如果我选择 UTF-8,它将生成 11 个字节的输出(因为“hello world”是 11 个字符长),但 UTF-16 将生成 22 个字节的输出。这两种编码会产生不同的摘要,因此了解编码至关重要。

    第二个答案是,摘要通常用于基于字符串的协议中,例如 HTTP cookie,用于将密码哈希存储在数据库的文本列中,用于将 PGP 签名添加到电子邮件等。

    由于摘要生成原始字节数组,因此需要将其重新编码为文本友好的内容。这就是为什么使用十六进制(或者更可能是 base-64)的原因。

    例如,以“hello world”为例,假设 UTF-8 编码的摘要转换为具有以下值的字节数组:4 27 125 8 0 22 90 7(用于我神话般的 8 字节摘要函数)。如果我试图将其解释为 UTF-8 字符串,那么我会得到很多垃圾:0 不是可打印的字符。以十六进制编码意味着我可以以有意义的方式将其打印出来,或将其添加到我的 PGP 电子邮件或其他任何内容中。

    这有意义吗?

    【讨论】:

    • 确实如此。这太棒了。谢谢。后续问题 - 当我在 linux 中使用“sha2sum”命令时,我假设它会执行上述操作(尽管使用的是 diff 语言而不是 Java)。该命令的输出是 base64 还是十六进制?
    • 不知道。如果它与“md5sum”相同(但使用 SHA2),那么我猜是十六进制。如果输出完全是 [0-9a-f] 那么它是十六进制;如果输出是 [a-zA-Z0-9+/] 那么它是 base64。您还可以计算字符数:十六进制是每个字符 4 位,因此 sha-256 哈希需要 64 个十六进制字符。 Base64 是每个字符 6 位,所以它只需要 43 个字符。
    【解决方案2】:

    这些散列算法的实现适用于字节,而不是字符串字符之类的其他东西。这就是为什么您需要将所有内容都转换为字节形式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      • 2015-05-01
      • 2021-01-07
      • 2021-11-19
      • 1970-01-01
      相关资源
      最近更新 更多