java.security.NoSuchAlgorithmException

list 00001 Mac.getInstance

Mac mac = Mac.getInstance("HmacSHA1");

報錯

java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available

原因,Eclipse 的項目的 jre 配置用的是jre, 改成 jdk 就好了

參照鏈接,另一個相似有啓發的問題

http://stackoverflow.com/questions/2856248/nosuchalgorithmexception-algorithm-hmacsha1-not-available
====================================================================

below is the main content of the link above.

Question :

Look at the following line of 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.

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

[quote]Copying sunjce_provider.jar
from $JAVA_HOME/jre/lib/ext
to the lib directory of the container.

Adding the following line to my code:[/quote]

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


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

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.

[b]Related question[/b]
: [url=http://stackoverflow.com/questions/1009996/using-java-crypto-leads-to-nosuchalgorithmexception]http://stackoverflow.com/questions/1009996/using-java-crypto-leads-to-nosuchalgorithmexception[/url]
.
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.

clew:

The startup script sets the java.ext.dirs
to 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.jar
resides. This explains your first point (copying the Jar file to the
lib directory makes it visible again). This is easily reproduced.

As for the second point, I think this is due the policy file that the startup script sets with the -Djava.security.policy
option. 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.

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.security
and contains (among others) the following lines:

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...).
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章