I'm trying to send a request with HttpsURLConnection to an endpoint with a custom SSL certificate but I am still getting PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(
utilService
.getCertificate(
item.getCertificatePath(), item.getCertificatePassword())
.getSocketFactory());
I have the certificates as files in the project, and I add them manually to the connection. The problem is that this works with some of the other websites I need, but there's one that still is throwing a 403 error.
I tried adding the certificate to the Java Keystore but the error still persists:
COPY /src/main/resources/transport.crt /home/transport.crt
RUN $JAVA_HOME/bin/keytool -import -file /home/transport.crt -alias certificate1 -keystore "/opt/openjdk-17/lib/security/cacerts" -trustcacerts -storepass changeit -noprompt
I don't really understand why adding the certificate manually to the connection doesn't work, nor why doesn't it work when I add it to the key store.
Related
I'm a bit lost of how I can use certificate in WidlFly 11. I re the doccumentation and found a lot of terms like JSSE, OpenSSL, Elytron, ApplicationRealm.
The problem occurs when I execute the code
final URL url = new URL("https://someUrl");
HttpsURLConnection httpURLConnection = (HttpsURLConnection)url.openConnection();
This exception is thrown sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
So, what exactly need to configure? I tried the section "Enable One-way SSL/TLS for Applications" in Elytron Doccumentation but didn't works.
ps: I'm using java 9.01
ps2: I'm using standalone-full.xml
let me know if you need more informations
This is unrelated to WildFly - you need to configure certificates trusted by java URL connections - you need to create and configure truststore:
create keystore containing certificate of server (if it is self-signed certificate), or better, certificate of its CA:
keytool -import -file myCA.cert -alias myCA -storepass mypassword -noprompt -keystore my.truststore
start using created keystore file as truststore in WildFly by setting javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword system properties:
bin/jboss-cli.sh -c
/system-property=javax.net.ssl.trustStore:add(value="/path/to/my.truststore")
/system-property=javax.net.ssl.trustStorePassword:add(value="mypassword")
Elytron documentation you mention is related only to server side - but this is client side configuration, which is not currently handled by it.
The certificate is not trusted, iirc there is a self-signed certificate in WildFly 11 so yo need to trust it or install a real certificate.
Accept server's self-signed ssl certificate in Java client
I have been re-searching this issue for the below and I have seen many people with the same issue. Upon my resolution, I was able to verify that I had an old certificate and was able to install the new certificate. Upon installing the new certificate in cacerts, I still receive the below when trying to download the file from the url.
cannot download the xml file
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: u
nable to find valid certification path to requested target
The commands that I used is below:
/app/financial/prd/thirdparty/java/bin/keytool -import -alias fincert1 -file /tmp/treasurydirect5.cer -keystore
/app/financial/prd/thirdparty/java/jre/lib/security/cacerts
As a last resort, I decided to ask the question on here because it has been asked multiple times with a resolution from the above. However, I'm still receiving the error after installing the new certificate.
I was able to confirm that the new certificate was installed by running the below:
/app/financial/prd/thirdparty/java/bin/keytool -list -v -keystore /app/financial/prd/thirdparty/java/jre/lib/security/cacerts -storepass <password>
Any additional details would be much appreciated. Thanks
I have Created CSR request using this command :
openssl req -out certificatecsr.csr -new -newkey rsa:2048 -keyout certificatekey.key
After that CA has shared certificate(.cer) file with me.
Now after that i have converted .cer file to .p12 using key.
Creating a .p12 certificate using cer sent by CA and private key
C:\Java\jdk1.6.0_38\jre\bin>openssl pkcs12 -export -in C:\Users\asharma1\cert.cer -inkey certificatekey.key -out
certi.p12
Creating JKS keystore :
keytool -genkey -alias quid -keystore quid.jks
importing .p12 certificate into jks keystore
C:\Java\jdk1.6.0_38\jre\bin>keytool -v -importkeystore -srckeystore C:\OpenSSL-Win64\bin\certi.p12 -srcstoretype PKCS12
-destkeystore quid.jks -deststoretype JKS
but when i am referring this JKS from my java code i am getting this error :
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I have also added cer file to cacerts.but still getting the same error.
As far as JAVA code is concerned i am refering this link to refer my own created keystore :
http://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/
public SSLContext getSSLContext(String tspath)
throws Exception {
TrustManager[] trustManagers = new TrustManager[] {
new ReloadableX509TrustManager(tspath)
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);
return sslContext;
}
SSLContext sslContext=getSSLContext("C:\\Java\\jdk1.6.0_38\\jre\\bin\\quid.jks");
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
URL pickUrl = new URL(pickupLocation);
URLConnection urlConn = pickUrl.openConnection();
HttpsURLConnection httpsURLConn = (HttpsURLConnection)urlConn;
httpsURLConn.setSSLSocketFactory(socketFactory);
String encoding = urlConn.getContentEncoding();
InputStream is = urlConn.getInputStream();
InputStreamReader streamReader = new InputStreamReader(is, encoding != null
? encoding : "UTF-8");
Please note i am not using any server. I am trying ti run above written code thorugh main method only.
Please let me know what need to be done.
Why do i need to convert my .cer file to .p12 file ?
I would suggest you import CA certificate (or whole chain of CA and intermediate CAs) to keystore.
I think that p12 was imported fine. What I am suggesting is import of the chain to keystore. At least that is what the error message is saying.
I presume that:
the root CA in the chain is not trusted so chain building fails or
there is no AIA section in certificates in the chain so no certificates up to trusted root CA can be fetched so chain building fails or
the certificates are not being fetched based on AIA because it is not implemented in java (I am not a java programmer) so chain building fails
You could use portecle to import missing trusted CA certificates (not end entity cartificate that you have in .p12 or in separate .cer file that you received from issuing CA). It is more user friendly than keytool. Just follow this guide.
I would suggest you use the *.der format instead of the .p12 format.
Here's an overall summary of how to import certificates to fix the following error:
Error while trying to execute request.
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
How to import certificates
Go to URL in your browser, click on HTTPS certificate chain (little lock symbol next to URL address) to export the certificate
Click "more info" > "security" > "show certificate" > "details" > "export..".
Save as .der
Repeat for any certificates you need to import
Locate $JAVA_HOME/jre/lib/security/cacerts
Import all *.der files into the cacerts file using the following:
sudo keytool -import -alias mysitestaging -keystore $JAVA_HOME/jre/lib/security/cacerts -file staging.der
sudo keytool -import -alias mysiteprod -keystore $JAVA_HOME/jre/lib/security/cacerts -file prod.der
sudo keytool -import -alias mysitedev -keystore $JAVA_HOME/jre/lib/security/cacerts -file dev.der
The default keystore password is 'changeit'
You can view the change that you made with this command that shows the Certificate fingerprint.
keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
If this doesn't solve the problem, try adding these java options as arguments:
-Djavax.net.ssl.trustStore="$JAVA_HOME/jre/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
I had to enable SSL over Active Directory server, to do that I followed each and every steps mentioned here: http://www.linuxmail.info/enable-ldap-ssl-active-directory/
Now I am not sure if SSL is really enabled properly?
On server itself if I run ldp, I think I can connect on 636 port. However on my system I don't see SSL option on ldp client?
I've two other LDAP clients (Softerra LDAP Browser and Apache Directory Studio) but I am not able to connect using ldaps (on 636 port). I guess I'll need to import certificate used in AD server so these tools can trust that self sign certificate which I used on AD server.
Using Java code, I've added certificate into cacerts (got certificate using steps mentioned here: http://www.linuxmail.info/export-ssl-certificate-windows-2003/), however I still can't connect to AD using SSL.
I tried SSL as well as TSL:
TLS:
// got LdapContext using ldap (not with ldaps)
StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
It gives following exception:
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
SSL:
String ldapURL = "ldaps://<domain-name>:636";
String keystore = "C:/Oracle/Middleware/jdk160_24/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore",keystore);
env.put(Context.SECURITY_PROTOCOL,"ssl");
// other properties are set in env
LdapContext ctx = new InitialLdapContext(env, null);
It gives following exception:
javax.naming.CommunicationException: <domain-name>:636 [Root exception is java.net.ConnectException: Connection timed out: connect]
Can anyone please suggest where I am wrong?
Thanks.
This one was fixed.
I was using wrong (rather incomplete) command to import certificate.
I was using:
keytool -import -alias mycert -keystore cacerts -file d:\mycert.cer
When I used follwing:
keytool -import -noprompt -trustcacerts -alias mycert -file c:/mycert.cer -keystore C:/Oracle/Middleware/jdk160_24/jre/lib/security/cacerts -storepass changeit
And it started working.
If you can't get TLS to work, it is unlikely that SSL will work. Are you sure that you got the right certificate and configured the keystore correctly? Based on the SSLHandshakeException when trying to use TLS, it would seem that may not be set up correctly.
Check out this SO answer for some tips on how to verify that your keystore is correctly set up: https://stackoverflow.com/a/9619478/1792088
I'm creating a Java client program that will be sending sensitive information to a Tomcat server. So I need to use SSL Connection so information will be encrypted.
I need to use self-signed untrusted certificate but having problems making connection from java client.
I have successfully setup Tomcat 5.5 to use SSL and tested it through Firefox, which displays warning of self-signed certificate.
I followed the Tomcat 5.5 SSL setup and they mentioned to create a keystore:
keytool -genkey -alias tomcat -keyalg RSA
Then I did an export of the above:
keytool -export -keystore .keystore -alias tomcat -file localhost.cer
Then I did an import of the above certificate into client machine:
keytool -import -alias tomcat -file localhost.cer -keystore "C:\Program Files"\Java\jdk1.6.0_17\jre\lib\security\cacerts"
But when running client I get:
Exception in thread "main" 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
This is the client code:
URL url = new URL("https://localhost:8443");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
Now I just started playing with these certificates today and I'm new to keystores, so please be patient.
Can someone please explain how to export and import the certificate created in Tomcat to client machine?
Thank you.
Atlassian has good instructions on how to fix this.
http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
Another approach is to install less unforgiving certificate validators, but that should only be done as a last resort.
Use Apache HTTP Cleint jar and follow this SSL Guide.
EasySSLProtocolSocketFactory can be used to create SSL connections that allow the target server to authenticate with a self-signed certificate.
I think you should input password using "changeit".