I am trying to use the sshj library to create an SFTP client in an existing project of my company. However if I create the SSHClient instance I get the error message:
[main] INFO net.schmizz.sshj.common.SecurityUtils - Registration of Security Provider 'org.bouncycastle.jce.provider.BouncyCastleProvider' unexpectedly failed
java.lang.SecurityException: JCE cannot authenticate the provider BC
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:118)
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:270)
at net.schmizz.sshj.common.SecurityUtils.registerSecurityProvider(SecurityUtils.java:88)
at net.schmizz.sshj.common.SecurityUtils.register(SecurityUtils.java:267)
at net.schmizz.sshj.common.SecurityUtils.isBouncyCastleRegistered(SecurityUtils.java:245)
at net.schmizz.sshj.DefaultConfig.<init>(DefaultConfig.java:79)
at net.schmizz.sshj.SSHClient.<init>(SSHClient.java:134)
[... junit stacktrace ...]
Caused by: java.util.jar.JarException: Class is on the bootclasspath
at javax.crypto.JarVerifier.verify(JarVerifier.java:286)
at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:164)
at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:190)
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:114)
... 40 more
[main] INFO net.schmizz.sshj.common.SecurityUtils - BouncyCastle not registered, using the default JCE provider
[main] INFO net.schmizz.sshj.transport.random.JCERandom - Creating new SecureRandom.
The application uses maven to include dependencies and I added it like this:
<dependency>
<groupId>com.hierynomus</groupId>
<artifactId>sshj</artifactId>
<version>0.27.0</version>
</dependency>
The sshj library includes the bouncycastle (BC) dependencies to bcpkix-jdk15on v1.60 and bcprov-jdk15on v1.60 and I've tried the following solutions:
Add the BC provider on my own, include the sshj and BC JARs directly as library and use the provided scope in maven as stated here. The provider is then added correctly but still fails with the error message from above.
Place the BC JARs in the jre/lib/ext folder.
Modify the java.security file as stated here.
Check if there is another BC version on the classpath as stated here.
However if I create a fresh project and include sshj everything is working just fine and as expected. I compared the commands which execute my junit test which crates the SSHClient and in both projects I can find the sshj JAR and the BC JARs included in the -classpath.
I am fairly new to maven and spring so I might be missing something obviously why everything is fine in a fresh project and not in the existing one, but I just can't figure it out.
If you need any more information I will gladly provide them!
There are 2 classpaths in Java, the bootclasspath and the regular classpath. The bootclasspath is where java.* and javax.* are located (jre/lib/rt.jar). But because that is not loaded by the system classloader, it is not supported to drop signed/verified jars in there. You need to ensure that the BouncyCastle jars are on the regular classpath (as specified using the -classpath option in the JRE/JDK
Related
I'm trying to get the library BioJava to work inside an OSGi context.
To get the JAR into the OSGi context, I'm using the Maven plugin p2-maven-plugin, which generates a file Manifest.MF, and the part relevant to the exception I'm facing is:
Bundle-SymbolicName: org.biojava.core
Bundle-Version: 5.3.0
Import-Package: [snip],
org.slf4j;resolution:=optional,
[snap]
Which looks okay to me. However when I access a class that uses slf4j I get the titular exception:
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.biojava.nbio.core.sequence.template.AbstractCompoundSet.<clinit>(AbstractCompoundSet.java:40)
at org.biojava.nbio.core.sequence.io.ABITrace.getSequence(ABITrace.java:179)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory cannot be found by org.biojava.core_5.3.0
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:511)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:414)
Now it's easy to find this exception everywhere, because a lot of people have tried (and failed) to install slf4j. I checked sites like the documentation or the SO question ClassNotFoundException: org.slf4j.LoggerFactory and hence tried to add the following bundles:
slf4j-simple
slf4j-log4j12 (plus the log4j dependencies)
pax-logging-log4j2
However neither worked. Maybe the OSGi container is having problems, but slf4j JARs have the bundle information with the export packages out of the box, so I'm assuming these work. And the BioJava JAR has an import package, so I have no idea why it wouldn't be able to find the class.
Oh, I checked, the LoggerFactory is present in slf4j-api, so it's not that, either.
I also tried different start levels and autostart for the implementations. And I rebundled the JAR without the optional dependency, but I keep having problems because now the MD5 hash is broken.
Has anybody managed to get slf4j to work in OSGi? Or failing that, is there any way to replace that stupid dependency with some kind of Java proxy so I will not need the broken dependency anymore?
resolution:=optional means that when the bundle resolves, it will either get access to the package or not. The framework is permitted to resolve the bundle without access to the package. If the bundle needs access to the package, why make resolution of the package optional?
In java 8 to setup a security provider I just needed to add the provider to the java.security file and add the provider external library to lib/ext. Since external libraries are not allowed in further versions how can I add a provider on jdk11?
Until now I tried to add the provider to the java.security file in conf/security folder.
security.provider.1=nCipherKM
I inserted the new provider on top of the list but when I try to .getInstance("providerExample") I still get a NoSuchProviderException.
java.security.NoSuchProvidIrException: no such provider: nCipherKM
The lib jar itself, I do not know where do I have to put or how can I include it to be recognized. If I create a lib/ext folder he says to use -classpath instead but also have no clue on that.
Thank you
EDIT: To complete my question I forgot to mention that im using thorntail and maven 3.6.1 to build the project. The error I get is related to this line:
KeyStore.getInstance("ncipher.sworld", "nCipherKM");
As I said before, when I had java 8 I only had to add the security.provider to the java.security and the nCipherKM.jar to $JAVA_HOME/lib/ext folder.
This question already has answers here:
Unable to derive module descriptor for auto generated module names in Java 9?
(2 answers)
Closed 5 years ago.
I am trying to build a demo project in java 9 with maven that uses the dependency:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-mllib_2.10</artifactId>
<version>2.2.0</version>
</dependency>
However when I run the jar tool to determine the automatic module name to use in my project's module-info.java I get the following error:
$ jar --file=spark-mllib_2.10/2.2.0/spark-mllib_2.10-2.2.0.jar --describe-module
Unable to derive module descriptor for: spark-mllib_2.10/2.2.0/spark-mllib_2.10-2.2.0.jar
spark.mllib.2.10: Invalid module name: '2' is not a Java identifier
It appears that the automatic module algorithm can't come up with a name that is valid java for this jar. Without adding the proper requires I get compile errors that the packages in spark mllib are missing such as:
package org.apache.spark.mllib.linalg does not exist
Is there anyway I can use this dependency in my project before it adds an official reserved module name or its own module-info?
For a proper, long-term solution the Apache Spark project must either add module declarations (module.info.java) to their JARs or set the Automatic-Module-Name entry in their JAR's manifest.
If you can't wait for that, you can do the latter yourself quite easily:
create a file manifest.txt with the following content:
Automatic-Module-Name: org.apache.spark.mlib2
Append that entry to the JAR's manifest:
jar --update --file spark-mllib_2.10.jar --manifest=manifest.txt
Make sure it worked:
jar --describe-module --file spark-mllib_2.10.jar
If you're planning to use this JAR in a real project, you would make it available to your colleagues, for which I would create a new version (maybe 2.10.patched-auto-name?), upload it to the company's Nexus and then edit the POMs to replace the original dependency with that one.
All in all, this is likely not worth the effort and you just might want to wait.
From the comments:
One thing to note is that the file you make the update with must end in a new line or the update silently fails.
Background
I am trying to use bouncy castle library to decrypt private keys in my war. Now I tested the code first in a standalone app and it worked fine. Now when I am testing it as a webapp in Wildfly8.0 am facing some issues with Bouncy castle.
The Wildfly 8.0 am using has bouncy castle provider module installed. The BC version being used in v1.46.
The code that I have developed uses v1.51.
I have followed the steps mentioned here:
https://developer.jboss.org/thread/175395
bouncycastle + JBoss AS7: JCE cannot authenticate the provider BC - Specifically followed instructions provided in For a specific deployment (preferred)
Already tried
Installing the JCE policy files.
Adding to the provider list.
Problem
The error I am getting is :
unable to read encrypted data: JCE cannot authenticate the provider BC
And the code which triggers the above error, in as follows :
PKCS8EncryptedPrivateKeyInfo kp = (PKCS8EncryptedPrivateKeyInfo) keyPair;
InputDecryptorProvider pkcs8dec = new JceOpenSSLPKCS8DecryptorProviderBuilder()
.setProvider(new BouncyCastleProvider())
.build("somepass".toCharArray());
PrivateKeyInfo pko = kp.decryptPrivateKeyInfo(pkcs8dec);<-- ##Error here
Also to add the details,in my pom.xml I have added the jar with compile scope, so the libs are copied into the war and get installed in WEB-INF/lib.
Any tips to fix the above problem?
I. Combining the idea of Peter (#comment) and https://developer.jboss.org/thread/175395, create "your own bc version" with a custom name:
Create an 'my.bouncycastle' module in the following manner:
Under $JBOSS_HOME/modules, create directory 'my/bouncycastle/main'. Directory 'my' might not be there. ;)
Copy bcprov-[your-version].jar into my/bouncycastle/main
Create file 'bcprov-[your-version].jar.index' in my/bouncycastle/main, which is basically the output of a jar -tf command without the ".class" lines. (pipe&edit...)
I put a blank line at the top because these .index files always seem to have one. I have attached this file as "bcprov-jdk16-1.46.jar.index".
Create a file called "module.xml", also in my/bouncycastle/main, which will point to the jar file and reference module "javax.api" as a dependency.
I have attached this file as 'module.xml'.
The module is complete.
Since I am deploying in an EAR file, I had to add a module dependency entry to my EAR's META-INF/jboss-deployment-structure.xml file, under the section, like so:
(the statement also applies to WAR files, when deployed on top-level, use the custom name as module reference)
<deployment><dependencies><module name="my.bouncycastle" slot="main" export="true"/>
Make certain that the ear's /lib directory does NOT contain bcprov-[your-version].jar. (actually II.)
Notes:
The 'slot="main" and 'export="true" parameters are very important in the jboss-dependency-structure.xml file...
II. Adjust your maven dependency(ies) to:
<scope>provided</scope>
Note: Don't change the maven dependecy(ies group artifacts) to "my.bouncycastle", only the scope, this will ensure you a nice compile-time-behavior by the most IDE's AND will prevent your (maven-)war/jar/ear-plugin from packaging it into libs! (And which would be anyway the correct scope for a dependency like this.)
I have problem with EAR module deployed in WAS6.
To support the MQ 7 features in my App. I follow the below steps:
Put Class loader policy as PARENT_LAST.
Placed all MQ 7 related jars in the root of EAR.
EAR contains Web module. When I try to start the application, I got following exception:
javax.servlet.jsp.JspException: Can't get definitions factory from context.
at org.apache.struts.taglib.tiles.InsertTag.processDefinitionName(InsertTag.java:575)
at org.apache.struts.taglib.tiles.InsertTag.createTagHandler(InsertTag.java:474)
at org.apache.struts.taglib.tiles.InsertTag.doStartTag(InsertTag.java:436)
at com.ibm._jsp._home._jspx_meth_tiles_insert_0(_home.java:106)
at com.ibm._jsp._home._jspService(_home.java:81)
The War contains the following jars.
xstream-1.3.1.jar,xercesImpl.jar, xalan.jar,struts.jar, standard.jar,commons-validator.jar, commons-net-1.4.0.jar, commons-fileupload.jar, commons-digester.jar, commons-collections.jar, commons-beanutils.jar,resolver.jar,jstl.jar, jfreechart-1.0.2.jar, jcommon-1.0.5.jar, jaxen-full.jar, jakarta-oro.jar.
EAR contains the following Jars,
com.ibm.mqjms.jar, com.ibm.mq.jmqi.jar, com.ibm.mq.jar, com.ibm.mq.headers.jar, com.ibm.mq.commonservices.jar,log4j.jar,dhbcore.jar.
And I set the class-path attribute in my Manifest file of the WAR with log4j.jar
Please anyone suggest me how Websphere's classloading policy works for where I went wrong.
Karthik
Some time ago I did something similiar. I wanted to use a specific version of a library which was already used within the WebSphere Application Server. That is the reason why you have to put your libraries in the EAR file and set the application server to PARENT_LAST class loader order.
Correct me if I am wrong, but you also have to specify your custom MQ client libraries in Manifest of your WAR file. You only mentioned Log4J. It should look somehting like this:
Class-Path: com.ibm.mqjms.jar com.ibm.mq.jmqi.jar [...] log4j.jar
Anyway, you can always check what libraries are in the Classpath of you application if you log into the Integrated Solutions Console (aka Admin Console) and check the Troubleshooting section. There is a classloader viewer. Just click yourself through the tree and check which library path are mentioned and which you would expect.
Finally, as Dylan already mentioned in his comment: WebSphere Application Server version 6.1 runs out of support September 30, 2012. :)