首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Mac.getInstance for HmacSHA1 slow

Java Mac.getInstance for HmacSHA1 slow
EN

Stack Overflow用户
提问于 2014-08-15 04:18:17
回答 1查看 2.6K关注 0票数 7

我在运行OSX10.9.4、1.7GHz i7、8GB内存的Macbook Air上运行以下Java程序。我已经安装了Java密码扩展(JCE)。

代码语言:javascript
复制
import javax.crypto.Mac;

public class Main {
  public static void main(String[] args) throws Exception {
    Mac.getInstance("HmacSHA1");
  }
}

运行这个简单的程序会导致运行时间超过5秒!

代码语言:javascript
复制
$ javac -version
javac 1.7.0_45
$ javac Main.java
$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
$ time java Main

real    0m5.326s
user    0m0.390s
sys     0m0.033s

我已经做了大量的搜索,但在解决方法或解释方面没有找到多少东西。

以前有人听说过这个问题吗?或者知道我怎么调试发生什么事了?当你的单元测试到现在为止都是瞬间的时候,对你的单元测试采取5秒的惩罚是非常令人沮丧的。

编辑:,这是程序内部的时间和安全提供者的列表:

代码语言:javascript
复制
import java.security.Provider;
import java.security.Security;
import javax.crypto.Mac;

public class Main {
  public static void main(String[] args) throws Exception {
    for (Provider p: Security.getProviders()) {
        System.out.println(p.getName() + " " + p.getVersion() + " " + p.getInfo());
    }
    long start = System.currentTimeMillis();
    Mac.getInstance("HmacSHA1");
    System.out.println(System.currentTimeMillis() - start + "ms");
  }
}

$ java Main
SUN 1.7 SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
SunRsaSign 1.7 Sun RSA signature provider
SunEC 1.7 Sun Elliptic Curve provider (EC, ECDSA, ECDH)
SunJSSE 1.7 Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
SunJCE 1.7 SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
SunJGSS 1.7 Sun (Kerberos v5, SPNEGO)
SunSASL 1.7 Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)
XMLDSig 1.0 XMLDSig (DOM XMLSignatureFactory; DOM KeyInfoFactory)
SunPCSC 1.7 Sun PC/SC provider
Apple 1.1 Apple Provider
5224ms

编辑2:

想出了如何在代码上运行HPROF

代码语言:javascript
复制
$ java -agentlib:hprof=cpu=times Main
$ cat java.hprof.txt
...
TRACE 308670:
java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:Unknown line)
java.net.InetAddress.getAddressesFromNameService(InetAddress.java:Unknown line)
java.net.InetAddress.getLocalHost(InetAddress.java:Unknown line)
javax.crypto.JarVerifier.getSystemEntropy(JarVerifier.java:Unknown line)
...
CPU TIME (ms) BEGIN (total = 6680) Sat Aug 16 05:59:39 2014
rank   self  accum   count trace method
   1 74.87% 74.87%       1 308670 java.net.InetAddress$1.lookupAllHostAddr
...

因此,由于某种原因,JarVerifier试图从系统中获取熵,这导致程序在InetAddress$1.lookupAllHostAddr中花费了5秒。

编辑3:

将Java更新为"1.7.0_67“并不能解决这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-16 21:36:32

我找到了解决办法。从编辑2中可以看出,Mac.getInstance()似乎调用了javax.crypto.JarVerifier.getSystemEntropy(),后者最终调用了java.net.InetAddress.getLocalHost()。根据这篇文章的说法,Java7改变了InetAddress查找本地主机的方式。由于某种原因,这会导致我的机器产生lookupAllHostAddr,这需要花费大约5秒的时间来完成。

本文中的一个注释列出了对我有用的解决方案,即将我的主机名添加到/etc/hosts中。以下内容如下:

代码语言:javascript
复制
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
fe80::1%lo0     localhost

更改为

代码语言:javascript
复制
127.0.0.1       localhost     <replace-me>.local
255.255.255.255 broadcasthost
::1             localhost
fe80::1%lo0     localhost

在对主机文件进行更改之后,我的时间又回到了合理的200 my。

代码语言:javascript
复制
$ time java Main

real    0m0.242s
user    0m0.379s
sys 0m0.034s
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25321187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档