问题描述
问题
我应该深入研究或解决似乎与 JCE 和 MongoDB 相关的问题有哪些可能的方法?
简要
多年来,我一直在开发基于 Java 的项目。今天遇到一个貌似和MongoDB和JCE有关的问题。我通过 IntelliJ 使用 Maven 将项目编译成一个 uber jar,并尝试在我的 Mac Pro 上执行 uber jar。
jar 可以一直执行,直到它尝试调用可以查看其源代码的 com.mongodb.DBPort$ScramSha1Authenticator$ScramSha1SaslClient.Hi
here。
不同 MongoDB 版本的异常消息
MongoDB版
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.14.3</version>
</dependency>
Exception in thread "main" java.lang.ExceptionInInitializerError
at javax.crypto.SecretKeyFactory.nextSpi(SecretKeyFactory.java:295)
at javax.crypto.SecretKeyFactory.<init>(SecretKeyFactory.java:121)
at javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:160)
at com.mongodb.DBPort$ScramSha1Authenticator$ScramSha1SaslClient.Hi(DBPort.java:839)
at com.mongodb.DBPort$ScramSha1Authenticator$ScramSha1SaslClient.computeClientFinalMessage(DBPort.java:760)
at com.mongodb.DBPort$ScramSha1Authenticator$ScramSha1SaslClient.evaluateChallenge(DBPort.java:694)
at com.mongodb.DBPort$SaslAuthenticator.authenticate(DBPort.java:917)
at com.mongodb.DBPort.authenticate(DBPort.java:445)
at com.mongodb.DBPort.checkAuth(DBPort.java:456)
at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:293)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:273)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:86)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:68)
at com.mongodb.DBCursor._check(DBCursor.java:498)
at com.mongodb.DBCursor._hasNext(DBCursor.java:621)
at com.mongodb.DBCursor.hasNext(DBCursor.java:657)
.
.
.
Caused by: java.lang.SecurityException: Can not initialize cryptographic mechanism
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:93)
... 20 more
Caused by: java.lang.SecurityException: The jurisdiction policy files are not signed by the expected signer! (Policy files are specific per major JDK release.Ensure the correct version is installed.)
at javax.crypto.JarVerifier.verifyPolicySigned(JarVerifier.java:336)
at javax.crypto.JceSecurity.loadPolicies(JceSecurity.java:378)
at javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:323)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:50)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:85)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:82)
... 20 more
MongoDB 版本
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.7</version>
</dependency>
.
.
.
Exception in thread "main" java.lang.ExceptionInInitializerError
at javax.crypto.Cipher.getInstance(Cipher.java:518)
at sun.security.ssl.JsseJce.getCipher(JsseJce.java:189)
at sun.security.ssl.SSLCipher.isTransformationAvailable(SSLCipher.java:483)
at sun.security.ssl.SSLCipher.<init>(SSLCipher.java:472)
at sun.security.ssl.SSLCipher.<clinit>(SSLCipher.java:81)
at sun.security.ssl.CipherSuite.<clinit>(CipherSuite.java:67)
at sun.security.ssl.SSLContextImpl.getApplicableSupportedCipherSuites(SSLContextImpl.java:345)
at sun.security.ssl.SSLContextImpl.access$100(SSLContextImpl.java:46)
at sun.security.ssl.SSLContextImpl$AbstractTLSContext.<clinit>(SSLContextImpl.java:577)
at java.lang.class.forName0(Native Method)
at java.lang.class.forName(Class.java:264)
at java.security.Provider$Service.getImplClass(Provider.java:1728)
at java.security.Provider$Service.newInstance(Provider.java:1686)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
at javax.net.ssl.SSLContext.getDefault(SSLContext.java:96)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:122)
at com.mongodb.MongoClientOptions.<clinit>(MongoClientOptions.java:60)
.
.
.
.
.
Caused by: java.lang.SecurityException: Can not initialize cryptographic mechanism
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:93)
... 24 more
Caused by: java.lang.SecurityException: The jurisdiction policy files are not signed by the expected signer! (Policy files are specific per major JDK release.Ensure the correct version is installed.)
at javax.crypto.JarVerifier.verifyPolicySigned(JarVerifier.java:336)
at javax.crypto.JceSecurity.loadPolicies(JceSecurity.java:378)
at javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:323)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:50)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:85)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:82)
... 24 more
一些信息
Mac Pro 上的 Java
$ sw_vers
ProductName: macOS
ProductVersion: 11.1
BuildVersion: 20C69
$ java -version
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09,mixed mode)
Intellij 上的 Java
adopt-openjdk-1.8 (1.8.0_275)
来自 Oracle JDK 8u161 发行说明中的 a mention:
JDK 使用 Java 加密扩展 (JCE) 权限策略文件来配置加密算法限制。以前,JDK 中的策略文件对各种算法进行了限制。此版本随附有限制和无限制的管辖权策略文件,默认为无限制。该行为可以通过 /lib/java.security 文件中的新“crypto.policy”安全属性进行控制。有关此属性的更多信息,请参阅该文件。
来自 Oracle JDK 8u261 发行说明中的 a mention:
自 2018 年 1 月(8u161、7u171)起,无限的 Java 加密扩展 (JCE) 权限策略文件已与 JDK 捆绑在一起并默认启用(请参阅 JDK 加密路线图)。
旧的独立 jar 的证书已过期,如果使用,将看到以下异常:
Caused By: java.lang.SecurityException: The jurisdiction policy
files are not signed by the expected signer!
(Policy files are specific per major JDK release.Ensure the correct version is installed.)
at javax.crypto.JarVerifier.verifyPolicySigned(JarVerifier.java:336)
at javax.crypto.JceSecurity.loadPolicies(JceSecurity.java:378)
at javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:323)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:50)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:85)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:82)
如果旧版本仍然需要重新签名的文件,请访问 https://www.oracle.com/java/technologies/oracle-java-archive-downloads.html
参考资料
- java.lang.SecurityException: The jurisdiction policy files are not signed by a trusted signer
- How to install unlimited strength JCE for Java 8 in OS X?
- Docs.microfocus.com。 2019. ITOM 从业者门户。 [在线] 可在:https://docs.microfocus.com/itom/Network_Operations_Management:2019.11/RemovalOfJCE [2021 年 1 月 22 日访问]。
- Oracle.com。 2018 年。Java™ SE 开发工具包 8,更新 161。 [在线] 可在:https://www.oracle.com/java/technologies/javase/8u161-relnotes.html#JDK-8170157 [2021 年 1 月 22 日访问]。
- Oracle.com。 2020 年。Java™ SE 开发工具包 8,更新 261 发行说明。 [在线] 可在:https://www.oracle.com/java/technologies/javase/8u261-relnotes.html#JDK-8245319 [2021 年 1 月 22 日访问]。
解决方法
这就是我最终解决的方法。
- 从 here 下载 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。
而且您需要注册成为 Oracle 会员,是的,没错! - 备份原始策略文件。
cd $JAVA_HOME/lib/security sudo cp US_export_policy.jar US_export_policy.jar.backup sudo cp local_policy.jar local_policy.jar.backup
- 在注册成为 Oracle 会员后放置您刚刚下载的策略文件。
sudo cp ~/Download/UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/lib/security/
我尝试用brew
安装openjdk8,仍然出现该现象(异常信息)。