【问题标题】:What specific hash algorithm does MessageDigest.getInstance("SHA") return?MessageDigest.getInstance("SHA") 返回什么特定的哈希算法?
【发布时间】:2013-02-15 21:23:48
【问题描述】:

MessageDigest.getInstance("SHA") 似乎工作并给了我一个MessageDigest,但我不知道它给了我什么算法。

是 SHA-1 还是 SHA-0 还是 ..?


我对我的机器上发生的事情不感兴趣。我想知道它是否会为所有有效的 Java 实现返回 sha0 或 sha1(或者它是未定义的)。

【问题讨论】:

  • 解决这个问题的简单方法是使用返回的任何内容来散列字符串“The quick brown fox jumps over the lazy dog”并检查输出。如果你得到2fd4e1c6-7a2d28fc-ed849ee1-bb76e739-1b93eb12,那么你就有了 SHA-1。 Lee Meador 的回答显示了一种查看 SHA 别名的编程方式。
  • @NikBougalis,您是否还检查了 sha-0 和 sha-1 是否出现相同的输出?我怎么知道它们可能不同?我什至在任何地方都找不到关于 sha-0 的描述。
  • @NikBougalis 引用需要
  • 摇头如果你愿意,请查看cc.utah.edu/~nahaj/ada/sha/sha-0 以获取SHA-0 的实现,获取它,编译它,执行它并自己测试它。事实是SHA-1 执行了滚桶操作,而SHA-0 没有。这显着改变了算法的输出(如果没有其他原因,因为雪崩效应)。如果任何字符串同时使用SHA-0SHA-1 散列到相同的值,那将是一个惊人的巧合。

标签: java cryptography undefined-behavior


【解决方案1】:

JCE Specification 列出了预期实现支持的标准名称。指定了“SHA-1”,以及 SHA-256、SHA-384 和 SHA-512。 “SHA”、“SHA-0”和“SHA-2”不是标准名称,因此可能根本不受支持。您不能保证“SHA”会返回什么,如果有的话,因为它不在标准中。

【讨论】:

  • 很好的答案。永远不要留下任何疑问,并使用真实姓名,而不是“别名”,如果可能,也不要将任何内容保留为默认值(例如,始终将 "AES/CBC/PKCS5Padding" 指定为 "AES" 将为 Cipher.getInstance() 返回 ECB 模式加密SunJCE 实现)。
  • 谢谢,这就是我要找的。所以换句话说,我的实际问题的答案是“既不/未定义”。
  • 如果我对这个问题的理解正确,那么您所指的是“标准名称”,例如可能使用的“SHA-384”和“SHA-512”。但绝不需要 Java 平台来支持这些算法。 MessageDigestthis url(谷歌“必须支持”)的 JavaDoc 都说需要 SHA-256,但不需要 SHA-384 或 SHA-512。
  • 这个 1997 年的 Java™ Cryptography Architecture API Specification & Reference 指定 SHASHA-1 相同。 2014 年的 Java 7 版本将声明移至 Java™ Cryptography Architecture Standard Algorithm Name Documentation,但为 MessageDigest 列出 SHA-1、SHA-256、SHA-384、SHA-512
【解决方案2】:

SHA-0 已过时。与 Java JCE MessageDigest 一起使用时,对于某些 JCE 提供程序,SHA == SHA-1。顺便说一句,SHA-1 在当今的计算机和技术中被认为是不安全的。 SHA-512 对于几乎任何东西来说仍然是安全的。 SHA-256 仍然适用于大多数情况。

您可以列出与此代码一起使用的 Java 版本中可用的协议。 (我知道了here):

import java.security.Provider;
import java.security.Security;

public class JceLook {

    public static void main(String[] args) {
        System.out.println("Algorithms Supported in this JCE.");
        System.out.println("====================");
        // heading
        System.out.println("Provider: type.algorithm -> className" + "\n  aliases:" + "\n  attributes:\n");
        // discover providers
        Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            System.out.println("<><><>" + provider + "<><><>\n");
            // discover services of each provider
            for (Provider.Service service : provider.getServices()) {
                System.out.println(service);
            }
            System.out.println();
        }
    }
}

它将显示所有可用算法的此类信息。 (请注意,这是上述程序针对 Oracle/Sun Java 6 的某些更新级别的实际输出,它表明 SHA 等效于 SHA-1 和 SHA1。您可以将三个字符串中的任何一个传递给 MessageDigest 并获得相同的结果. 但这取决于 Cryptography Provider (JCE),可能不一样。)

SUN: MessageDigest.SHA -> sun.security.provider.SHA
  aliases: [SHA-1, SHA1]
  attributes: {ImplementedIn=Software}

如果您加载其他提供程序(例如 BouncyCastle),它也会显示这些。

【讨论】:

  • 我对我的机器上发生的事情不感兴趣。我想知道它是否会为所有有效的 Java 实现返回 sha0 或 sha1(或者它是未定义的)。
  • 我怀疑它是未定义的,但我非常怀疑 any 的 Java 实现会返回 SHA-0。它在发现并纠正设计缺陷后被撤回,产生SHA-1
  • “但这取决于密码学提供程序 (JCE),可能不一样。”哎呀。那么你怎么能确定你调用了正确的哈希函数呢? @NikBougalis 我会有点惊讶,因为我不知道任何需要 SHA-0 的应用程序,但最好是安全而不是抱歉。
  • 对不起@megazord。密码学是一个你必须一丝不苟的地方。为什么不直接使用 SHA-1 而不是 SHA 来确保获得算法或获得异常?
  • @Lee Meador:我从未说过我在使用 SHA 甚至 SHA-1。我正在分析一些现有的代码。对于我正在使用的 which 加密哈希,我不必花费超过 1 秒的时间来推理。在 C 语言中,这很容易找到,junk = Sha_Init(),我只需查看我正在调用的函数的源代码/文档,它并没有“从我身上抽象出知道我正在使用哪个哈希的麻烦” , Java Crypto API 可以。
猜你喜欢
  • 2012-12-30
  • 1970-01-01
  • 2014-08-01
  • 2014-02-03
  • 2020-05-22
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多