Axl*_*xle 7 java random macos cryptography hmac
我在运行OSX 10.9.4,1.7GHz i7,8GB内存的Macbook Air上运行以下Java程序.我安装了Java Cryptography Extension(JCE).
import javax.crypto.Mac;
public class Main {
public static void main(String[] args) throws Exception {
Mac.getInstance("HmacSHA1");
}
}
Run Code Online (Sandbox Code Playgroud)
运行这个简单的程序会导致运行时间超过5秒!
$ 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
Run Code Online (Sandbox Code Playgroud)
我做了很多搜索,但没有找到解决方法或解释的方法.
HmacSHA1的Mac.getInstance()需要很长时间才能执行
这听起来类似我的问题,但我读过的所有消息来源指出,/dev/random与/dev/urandom上OSX相同.
再次讨论SecureRandom的随机性来源,但似乎并不适用于OSX.
以前有人听说过这个问题吗?或者知道一种方法让我调试正在发生的事情?当你的单位测试一直持续到目前为止,对你的单位测试给予5秒的惩罚是非常令人沮丧的.
编辑: 这是程序内部的时间安排和安全提供程序列表:
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
Run Code Online (Sandbox Code Playgroud)
编辑2:
弄清楚如何在代码上运行HPROF.
$ 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
...
Run Code Online (Sandbox Code Playgroud)
因此,似乎由于某种原因,JarVerifier试图从系统中获取熵,这导致程序在InetAddress $ 1.lookupAllHostAddr中花费5秒...
编辑3:
将Java更新为"1.7.0_67"并不能解决问题.
我找到了解决方案.在编辑2中可以看到,Mac.getInstance()似乎调用javax.crypto.JarVerifier.getSystemEntropy(),最终调用java.net.InetAddress.getLocalHost().根据这篇文章,Java 7改变了InetAddress寻找本地主机的方式.由于某种原因,这导致我的机器lookupAllHostAddr,这需要约5秒钟完成.
本文的一条评论列出了适合我的解决方案,即添加我的主机名/etc/hosts.下列:
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost
Run Code Online (Sandbox Code Playgroud)
改变为
127.0.0.1 localhost <replace-me>.local
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost
Run Code Online (Sandbox Code Playgroud)
更改为hosts文件后,我的时间又恢复到合理的200毫秒.
$ time java Main
real 0m0.242s
user 0m0.379s
sys 0m0.034s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1829 次 |
| 最近记录: |