java NoSuchAlgorithmException:算法 HmacSHA1 不可用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2856248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:10:21  来源:igfitidea点击:

NoSuchAlgorithmException: Algorithm HmacSHA1 not available

javacryptographyjcejames

提问by itsadok

Look at the following line of java:

看下面这行java:

Mac.getInstance("HmacSHA1");

If I put this in a simple test program, it runs without problems on my server. However, if I use this line in a container, I get

如果我把它放在一个简单的测试程序中,它在我的服务器上运行没有问题。但是,如果我在容器中使用这条线,我会得到

java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available
  at javax.crypto.Mac.getInstance(DashoA13*..)

The same JDK installation is used in both cases.

在这两种情况下都使用相同的 JDK 安装。

After googling around a bit, I managed to get it to work by doing two things:

在谷歌搜索了一下之后,我通过做两件事设法让它工作:

  1. Copying sunjce_provider.jarfrom $JAVA_HOME/jre/lib/extto the lib directory of the container.
  2. Adding the following line to my code:

    java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

  1. 复制sunjce_provider.jar$JAVA_HOME/jre/lib/ext该容器的lib目录。
  2. 将以下行添加到我的代码中:

    java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

Specifically, this happens to me in an Apache Jamesmailet, but I'm pretty sure this is has to do with JVM options. Here is the startup scriptthat it uses.

具体来说,这发生在我的Apache Jamesmailet 中,但我很确定这与 JVM 选项有关。这是它使用的启动脚本

Although I got it to work in the end, the solution feels too hacked to be the right one. I would appreciate an explanation of what is going on, as well as a more "proper" solution.

虽然我最终让它工作了,但这个解决方案感觉太糟糕了,无法成为正确的解决方案。我将不胜感激对正在发生的事情的解释,以及更“正确”的解决方案。

Related question: Using Java crypto leads to NoSuchAlgorithmException. However, in this case I'm pretty sure the HmacSHA1 algorithm should be supported out of the box. As evidence, this works without problems in a test program.

相关问题使用 Java 加密会导致 NoSuchAlgorithmException。但是,在这种情况下,我很确定应该立即支持 HmacSHA1 算法。作为证据,这在测试程序中没有问题。

回答by Thomas Pornin

The startup script sets the java.ext.dirsto its own set of directories (specific to the application) but omitting the "normal" extension directory ($JAVA_HOME/jre/lib/ext/) which is where sunjce_provider.jarresides. This explains your first point (copying the Jar file to the lib directory makes it visible again). This is easily reproduced.

启动脚本将 设置java.ext.dirs为它自己的一组目录(特定于应用程序),但省略了“普通”扩展目录 ( $JAVA_HOME/jre/lib/ext/)sunjce_provider.jar所在的位置。这解释了您的第一点(将 Jar 文件复制到 lib 目录使其再次可见)。这很容易重现。

As for the second point, I think this is due the policy file that the startup script sets with the -Djava.security.policyoption. Whether some providers are available or not depends on policy files. The default policy file makes the SunJCE provider available, but since the startup scripts mandates a non-default, custom policy file, then anything goes. I suggest you take a look at that policy file.

至于第二点,我认为这是由于启动脚本使用该-Djava.security.policy选项设置的策略文件。某些提供程序是否可用取决于策略文件。默认策略文件使 SunJCE 提供程序可用,但由于启动脚本强制要求使用非默认的自定义策略文件,因此一切都会发生。我建议你看看那个策略文件。

For instance, on my system (Ubuntu Linux, with Sun JVM 1.6.0_20 as packaged by Ubuntu), the default policy file is in /etc/java-6-sun/security/java.securityand contains (among others) the following lines:

例如,在我的系统(Ubuntu Linux,使用 Ubuntu 打包的 Sun JVM 1.6.0_20)上,默认策略文件位于/etc/java-6-sun/security/java.security并包含(除其他外)以下几行:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.8=sun.security.smartcardio.SunPCSC

which define what providers should be available by default. From your symptoms, I think that the custom policy file made SunJCE unavailable unless explicitly registered (which is understandable since the startup script also removed the access to the Jar file containing SunJCE...).

它定义了默认情况下应该可用的提供程序。从您的症状来看,我认为除非明确注册,否则自定义策略文件使 SunJCE 不可用(这是可以理解的,因为启动脚本还删除了对包含 SunJCE 的 Jar 文件的访问权...)。

回答by ppostma1

It was shortened to SHA1, MD5, and SHA256

它被缩短为 SHA1、MD5 和 SHA256

回答by Vishrant

Try to change the Java version

尝试更改 Java 版本

I was getting exception NoSuchAlgorithmException: "Unable to obtain JCA MAC algorithm 'HmacSHA512'"on following Java version:

NoSuchAlgorithmException: "Unable to obtain JCA MAC algorithm 'HmacSHA512'"在以下 Java 版本中遇到异常:

java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

java 版本“1.8.0_131”
Java(TM) SE 运行时环境(构建 1.8.0_131-b11)
Java HotSpot(TM) 64 位服务器 VM(构建 25.131-b11,混合模式)

After changing the JDK version to following the issue was resolved:

将JDK版本更改为以下问题后,问题得到解决:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

java 版本“1.8.0_45”
Java(TM) SE 运行时环境(构建 1.8.0_45-b15)
Java HotSpot(TM) 64 位服务器 VM(构建 25.45-b02,混合模式)

The required jar for this issue is sunjce_provider.jarit is possible that it might be corrupt.

此问题所需的 jarsunjce_provider.jar可能已损坏。

回答by Alex George

The correct shortened form is as below

正确的缩写形式如下

HmacMD5
HmacSHA1
HmacSHA256