在我的Web应用程序中,登录密码被哈希并使用JasyptStringDigester和SHA256保存。在登录过程中,用户输入的密码将与同一个摘要器进行哈希比较。

但是,在应用程序运行约2天后,登录突然变得非常缓慢。一旦发生,我必须重新启动服务器才能恢复。

通过线程转储,我发现速度下降是由摘要器引起的,它消耗了CPU资源。我试图将JCE提供者从默认的提供者更改为bouncycastle,但这没有帮助。

发生此问题时,我还检查了JVM中的Momery用法,但其中有很多。

环境:

JDK 7u60

JBoss 7.1.1最终版

Digester配置(用作单例):

<bean id="jasyptStringDigester" class="org.jasypt.digest.StandardStringDigester">
		 <property name="provider" ref="bouncyCastleProvider" />
          <property name="algorithm" value="SHA-256" />
          <property name="iterations" value="100000" />
          <property name="saltGenerator">
               <bean id="zeroSaltGenerator" class="org.jasypt.salt.ZeroSaltGenerator"/>
          </property>
          <property name="saltSizeBytes" value="10"/>
</bean>


<bean id="bouncyCastleProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>


线程转储:

	"ajp--10.88.90.34-8009-22" daemon prio=10 tid=0x00007ff2100ad800 nid=0xc7e runnable [0x00007ff1a9ae4000]
   java.lang.Thread.State: RUNNABLE
        at org.bouncycastle.crypto.digests.SHA256Digest.Sum0(Unknown Source)
        at org.bouncycastle.crypto.digests.SHA256Digest.processBlock(Unknown Source)
        at org.bouncycastle.crypto.digests.GeneralDigest.finish(Unknown Source)
        at org.bouncycastle.crypto.digests.SHA256Digest.doFinal(Unknown Source)
        at org.bouncycastle.jcajce.provider.digest.BCMessageDigest.engineDigest(Unknown Source)
        at java.security.MessageDigest.digest(MessageDigest.java:353)
        at java.security.MessageDigest.digest(MessageDigest.java:399)
        at org.jasypt.digest.StandardByteDigester.digest(StandardByteDigester.java:979)
        - locked <0x0000000748e4a9c0> (a org.bouncycastle.jcajce.provider.digest.SHA256$Digest)
        at org.jasypt.digest.StandardByteDigester.digest(StandardByteDigester.java:933)


有人可以帮忙吗?我已经被这个问题困扰了很长时间了。在https://bugs.openjdk.java.net/browse/JDK-8023983中发现了类似的问题,但是我找不到任何解决方案。

谢谢。

最佳答案

我有完全一样的问题,熵不是原因。 SHA256摘要不需要随机。问题在于JIT(及时)编译机制,该机制允许直接在本机代码中编译某些Hotspot函数。 JDK7中存在一个已知问题,请参见:http://www.oracle.com/technetwork/java/javase/documentation/javase7supportreleasenotes-1601161.html在代码缓存已满时禁用本机编译器。在这种情况下,SHA摘要不是本地执行的,因此会变得很长!

要重现,只需禁用编译器:

-Djava.compiler=NONE

解决方案是迁移到Java 8,Java 7的一种解决方法是使用JVM选项根据您的需要增加CodeCache的大小。
-XX:ReservedCodeCacheSize=300m
您可以通过JConsole监视代码缓存:

java - 带有SHA2的JasyptStringDigester突然变得非常缓慢-LMLPHP

我希望这会有所帮助:)

埃里克

10-06 09:11