I am now trying to access the web service via https and to achieve this i have done the below.
I used the below commands to generate the self signed certificate and placed in /conf dir.
keytool -genkey -alias localhost -keyalg RSA -validity 365 –keystore server.keystore –storetype JKS
keytool -export -alias localhost –keystore server.keystore -rfc -file public.cert
keytool -import -alias localhost -file public.cert –storetype JKS -keystore server.truststore
Below is the server.xml entry
<Connector className="org.apache.catalina.connector.http.HttpConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true"
acceptCount="10" debug="0" scheme="https" secure="true">
<Factory className="org.apache.catalina.net.SSLServerSocketFactory"
keystoreFile="conf/server.keystore"
keystorePass="changeit"
truststoreFile="conf/server.truststore"
truststoreType="JKS" truststorePass="changeit"
clientAuth="false" protocol="TLS"/>
</Connector>
And now i am facing the below error.
{http://xml.apache.org/axis/}stackTrace: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
However the error is not thrown if i add the below code in the class file accessing the webservice.
AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
Could you please guide me in resolving this issue?
TLS is being set up on two sides: server and client. Each side must have its own key pair saved into a key store. Let's call them serverKeystore.jks and clientKeystore.jks
Then additional key store is to be created containing only public key. This one is called trust store and used for key authentication. Let's follow the same scheme and save them into serverTruststore.jks and clientTruststore.jks.
In one way TLS only server key is being authenticated.
Server must have only serverKeystore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
In two way TLS both server and client keys are being authenticated.
Server must have serverKeystore.jks and clientTruststore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
Client registers key stores either by specifying Java environment variable with
-Djavax.net.ssl.keyStore="path\\to\\server.keystore"
in parameters to command starting JVM, or programmatically in the code with
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
Technically it is possible to use the same key pair both on client and server side as you did. But this compromises the private key, as it is not secret any more.
The below entry is added in the class file where the call to https would happen and it works like charm. Yet i am not sure why the xml entry is not considered.
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", "path\\to\\server.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
PS: Both xml entry and the class entry is needed else the same error is thrown. I am yet to get a clear picture on this. Maybe someone might explain. Thanks
Related
I got a serious problem while making an SSL request to the server with SOAPUI. I am a newbie in SoapUI and maybe I did something wrong while I'm trying to import the certificate into SOAPUI.
My client sends me:
Root CA
Intermediate CA
SSL CA
Private Key
I am using keytore to generate keystore with password by command
keytool -genkey -alias soapui -keyalg RSA -keystore soapui.keystore
And then I tried to export the this keystore with my SSL CA
keytool -export -alias soapui -file SSL.cer -keystore soapui.keystore
And then I import this into Keystores in the SoapUI.
However, I got the error
ERROR:java.security.KeyStoreException: Can't build keystore: [Private key missing (bad password?)]
I have no idea where am I wrong?
Could anyone please indicate what are the steps I should work on to make the SSL request to SoapUI?
Please help
Thank you.
I assume you need to make a Two-Way SSL connection with client cetificate.
Firstly you need to make a keystore (JKS) containing:
your private key
all certificates upwards including the root CA
Maybe using https://keystore-explorer.org/ may help you to understand and verify the content of your keystore.
There are multiple ways to configure the client certificate in SoapUI:
If you use the global configuration (File - Preferences - SSL Settings), there is only one password to be set. Make sure your keystore password and key password are equal.
If you use the setup on the project level, you are allowed to enter two passwords.
I have an ActiveMQ Broker living on AWS. I'm trying to secure connections from clients using SSL. I have set up the broker to use SSL, but I don't quite understand where the clients are supposed to get the certificate from. Do I need to copy the cert from the broker and package it with client code? Or do I remotely retrieve the cert programmatically each time the client is launched?
Relevant SSL Setup in activemq.xml
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/broker.ks"
keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts"
trustStorePassword="password"/>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
</transportConnectors>
The clients connecting will be Java clients using JMS. At this point I'm using the default cert that comes packaged with the ActiveMQ installation.
As the ActiveMQ documentation states:
ActiveMQ includes key and trust stores that reference a dummy self signed cert. When you create a broker certificate and stores for your installation, either overwrite the values in the conf directory or delete the existing dummy key and trust stores so they cannot interfere)
Therefore, you should delete the existing broker.ks and broker.ts and create new ones for your installation. You've got a couple of options here.
I imagine that AWS has some sort of infrastructure to acquire SSL certificates and that those certificates would be signed by a well-known certificate authority which would be trusted implicitly by your JMS clients. A quick search turned up AWS Certificate Manager.
However, you also have the option of using a "self-signed" certificate which is, by definition, not signed by a well-known certificate authority and therefore must be explicitly trusted by your clients.
You can take the self-signed route by using the following commands:
Using keytool (from the JDK), create a certificate for the broker:
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
Export the broker's certificate so it can be shared with clients:
keytool -export -alias broker -keystore broker.ks -file broker_cert
Create a certificate/keystore for the client:
keytool -genkey -alias client -keyalg RSA -keystore client.ks
Create a truststore for the client, and import the broker's certificate. This establishes that the client "trusts" the broker:
keytool -import -alias broker -keystore client.ts -file broker_cert
When starting the client's VM, specify the following system properties:
javax.net.ssl.trustStorePassword=password
javax.net.ssl.trustStore=/path/to/client.ts
If you choose the self-signed route then you only need to generate the client.ts once and then copy that to every client. The clients will use the same truststore every time they connect (assuming the broker's certificate doesn't change).
So I bought a certificate I got a certificate, a key, and intermediate that has 2 beginnings I dont know if that counts or should be add as separated intermediate.
I added the certificate and the intermidate like this.
keytool -import -trustcacerts -alias rootmydomain -file rootmydomain.crt -keystore mykeystore.keystore
keytool -import -trustcacerts -alias interm.mydomain -file interm.mydomain.crt -keystore mykeystore.keystore
I didnt have a problem so far, it crated a mykeystore.keystore file in my wildfly/standalone/configuration/ folder. I was even able to list my entries in mykeystore.keystore.
Then added the following to my standalone.xml.
<security-realm name="ssl-realm">
<server-identities>
<ssl>
<keystore path="mykeystore.keystore" relative-to="jboss.server.config.dir" keystore-password="mypassword" alias="rootmydomain" key-password="mypassword"/>
</ssl>
</server-identities>
</security-realm>
And I get the followin error:
04:55:22,538 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.server.controller.management.security_realm.ssl-realm.key-manager: org.jboss.msc.service.StartException in service jboss.server.controller.management.security_realm.ssl-realm.key-manager: WFLYDM0083: The KeyStore /opt/wildfly-10.0.0.Final/standalone/configuration/mykeystore.keystore does not contain any keys.
I had the same configuration with an cert generated by myself and it worked. I dont know why I am not able to make is work like this.
Based on the commands you issued, there are indeed no keys in your keystore, just certificates. You need to get your private key in the keystore in order for Wildfly to be able to pick it up.
importing an existing x509 certificate and private key in Java keystore to use in ssl is an example of how it can be done.
I'm having trouble getting ColdFusion to connect to a secure FTP server that uses a self-signed certificate. The connection just times out. I've tested the setup in an FTP client and it works, but you must accept an 'unknown certificate.'
The code, though it's not very helpful:
<cfftp
connection="ftp"
action="open"
server="server"
username="username"
password="password"
port="23456"
passive="true"
secure="true"
/>
Here's the error I get from ColdFusion:
Verify your connection attributes: username, password, server, fingerprint, port, key, connection, proxyServer, and secure (as applicable). Error: Session.connect: java.net.SocketTimeoutException: Read timed out.
Does anyone know if it's possible to accept the certificate? Or if that's even the problem?
I am not sure about cfftp but for cfhttp requests to sites with a self-signed certificate you have to import their certificate into the Java keystore on your ColdFusion server. So you might want to give that a try.
I always export the certificate in DER format
The command to import should be something like this:
keytool -import -v -alias giveUniqueName -file filename.cer -keystore cacerts -storepass thePassword
Here is the command line to verify an imported certificate:
keytool -list -v -keystore cacerts -alias giveUniqueName -storepass thePassword
I did not include the password here but am pretty sure you can Google it. If not, send me a message and I can give it to you.
Also, you may need to supply pathing information depending on where you run the keytool commands from and where your certificate file resides.
Another note, be sure you are updating the correct cacerts file that ColdFusion is using. In case you have more than one JRE installed on that server. You can verify the JRE ColdFusion is using from the administrator under the 'System Information'. Look for the Java Home line.
Oh - and you have to restart ColdFusion after making the import.
UPDATE FOR CF10
I found a forum discussion (here) talking about installing certificates on CF10. The keytool commands appear to be slightly different in their example. In case it is a bit different than CF9, here is what they said:
keytool -importcert -alias giveUniqueName -trustcacerts -file filename.cer -keystore cacerts -storepass thePassword
Trust this certificate? [no]: y
It looks like the verification command line has not changed.
I'm trying to request data from a web service which requires a client certificate to be presented by a client. The server uses SSL for all communications, and uses a self-signed certificate. I gave Netbeans the service's WSDL file and it generated client code with wsimport.
I have no issues when my client code is written in a regular Java application; I set the trust store to the cacerts file containing the server's certificate, set the key store to be a file provided by the server admin in JKS format containing 2 keys - a client private key and the server's public key, build the request object, and send the request.
The problem comes when I move it to an enterprise Java environment. Requirements dictate that the code must be an Enterprise JavaBean inside an Enterprise Archive running on the Glassfish application server. It appears that Glassfish has its own security settings which override the JVM's settings. When the EJB method containing the web service call runs, the SSL negotiation fails: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. I don't know how to set Glassfish's security settings up like my JVM's settings, can anyone explain Glassfish's security settings? The research I have done has only shown how to set up Glassfish as a web service server, not as a web service client.
I have a .cer certificate file for the server which I added it to my trust store by using Java's keytool to add it to the default cacerts file.
Would it be better to modify cacerts file with InstallCert to include the self-signed certificate, following the steps at http://blog.johnryding.com/post/1548502059/acquire-an-ssl-certificate-for-your-java-programs-in-win?
I have the trust store file, key store file, along with a .cer certificate file and a .p12 browser certificate, stored in $JAVA_HOME/jre/lib/security and $JAVA_HOME/lib/security.
I'm using Netbeans 6.9.1 and Glassfish 3.1 Final. The relevant piece of code is below, copied from my EJB. The exception occurs at the last line.
System.setProperty("javax.net.ssl.trustStore", "C:\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStore", "C:\\userCertificate.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
RequestObject request = new RequestObject;
request.setQuery("some data");
request.setUsername("user");
request.setPassword("pass");
Service service = new Service();
Endpoint port = service.getWebServicePort();
Result result = port.specificWebServiceMethod(request);
I faced the same exception that Jacques Pritchard described above:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I solved it importing the root certificate in both cacerts.jks and keystore.jks, using the following commands:
/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore cacerts.jks
/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore keystore.jks
It's important to say that the alias rootca is a name I defined myself to label the certificate. You can choose any name also.
Instead of using the global system properties, you should create a separate SSLContext for your client. Whether or not it runs within a Glassfish server doesn't really matter, then.
Here is a question that should be relevant (about client-certificates for WS): Choosing SSL client certificate in Java
I had this exact problem (with Glassfish 3.0.1).
Here are the exact steps we took to resolve this.
a. Use java keytool command to view the keystore to see what's in it. This is helpful later on to see if there are any changes. The command goes something like
keytool -list -keystore MyKeyStore.jks
b. Convert the pfx to a pem using openssl. Note that I used the correct password for the input pfx and the same password as my java keystore for the pem file output.
openssl pkcs12 -in MyPfxFile.pfx -out MyPemFile.pem
Convert the pem file to a p12 which can easily be imported into a java keystore. Note that I used the same password from my java keystore as I did on the input and output files.
openssl pkcs12 -export -in MyPemFile.pem -out MyP12File.p12
Now I finally import the p12 into my java keystore. Note that I used java 6, java 5 keytool doesn't have support for the -importkeystore argument.
keytool -importkeystore -deststorepass MyPassword -destkeystore PathToMyKeystore/keystore.jks -srckeystore MyP12File.p12 -srcstoretype PKCS12 -srcstorepass MyPassword
You can list the keystore contents here, something like this keytool -list -keystore keystore.jks just to ensure that your new key was imported correctly.
If you're lucky like I am you'll find that starting up your app server at this point will be of no use. You'll see errors like something about pkix path or something about HTTP 403 Forbidden.
The steps used above worked perfectly for Sun Application Server 9.1_1 but not for Oracle Glassfish 3.0.1. I'm thinking this has something to do with the version of JSSE used in ogs 3 compared to Sun App Server or jdk versions. Adding the jvm option below to your ogs 3 domain.xml file should resolve the issue if simply adding the client cert to the keystore didn't.
<jvm-options>-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol</jvm-options>
I did notice that someone said to not use the jvm options statement above but it's part of the fix, don't use it and see if it works, I'll bet it won't. Maybe just changing the handlers is why it works?
Here's where I found the details: http://onjava.com/pub/a/onjava/2001/05/03/java_security.html?page=4
I also stumbled across a final issue (only for ogs 3), if you get fails every now and again I'd suggest finding the InstallCert app (its out there) and give it the following command line parameters:
I was getting these PKIX errors every third attempt at calling the web service.
Hopefully this helped someone else out. These kind of issues really make me want to rip my hair out :)
I finally got it.
Removed all the certs from my keytool.
Command Example : keytool -list -v -keystore keystore.jks -alias mydomain
I converted the cert response from server to bas64 DER and copied them into one file a .PEM, and I uploaded the .PEM into my keytool:
Command Example : keytool -importcert -keystore keystore.jks -alias mydomain -file my.pem
Then I loaded the keystore:
KeyStore myStore = KeyStore.getInstance("JKS");
InputStream keyInputx = new FileInputStream("C:\\myStore.jks");
myStore.load(keyInputx, "xxx".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyInputx.close();
/*Enumeration enumeration = myStore.aliases();
while (enumeration.hasMoreElements()) {
String alias = (String) enumeration.nextElement();
System.out.println("alias name: " + alias);
Certificate certificate = myStore.getCertificate(alias);
System.out.println(certificate.toString());
}*/
keyManagerFactory.init(myStore, "xxx".toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
SSLSocketFactory sockFact = context.getSocketFactory();
Lots of references around so be happy to use.