Question
What are possible ways I should dive into or could fix the issue seemingly related to JCE and MongoDB?
Brief
I've been developing a Java-based project for years. Today, I encountered an issue seemingly related to MongoDB and JCE. I compiled the project into an uber jar using Maven via IntelliJ and attempted to executed the uber jar on my Mac Pro.
The jar could be executed until it tried to call com.mongodb.DBPort$ScramSha1Authenticator$ScramSha1SaslClient.Hi
whose source code can be viewed here.
Exception Message with Different MongoDB Versions
MongoDB version
<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 version
<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
Some Info
Java on Mac Pro
$ 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)
Java on Intellij
adopt-openjdk-1.8 (1.8.0_275)
From a mention in the release notes of JDK 8u161 by Oracle:
The JDK uses the Java Cryptography Extension (JCE) Jurisdiction Policy files to configure cryptographic algorithm restrictions. Previously, the Policy files in the JDK placed limits on various algorithms. This release ships with both the limited and unlimited jurisdiction policy files, with unlimited being the default. The behavior can be controlled via the new 'crypto.policy' Security property found in the /lib/java.security file. Please refer to that file for more information on this property.
From a mention in the release notes of JDK 8u261 by Oracle:
Since January 2018 (8u161, 7u171) unlimited Java Cryptography Extension (JCE) Jurisdiction Policy files have been bundled with the JDK and enabled by default (see JDK Cryptographic Roadmap).
The certificate for the old stand alone jar has expired, and if used the following exception will be seen: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)
If still required for older releases the re-signed files can be found at https://www.oracle.com/java/technologies/oracle-java-archive-downloads.html
References
- 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 Practitioner Portal. [online] Available at: https://docs.microfocus.com/itom/Network_Operations_Management:2019.11/RemovalOfJCE [Accessed 22 January 2021].
- Oracle.com. 2018. Java™ SE Development Kit 8, Update 161. [online] Available at: https://www.oracle.com/java/technologies/javase/8u161-relnotes.html#JDK-8170157 [Accessed 22 January 2021].
- Oracle.com. 2020. Java™ SE Development Kit 8, Update 261 Release Notes. [online] Available at: https://www.oracle.com/java/technologies/javase/8u261-relnotes.html#JDK-8245319 [Accessed 22 January 2021].