Try as I might, I can't figure out how to use a .p12 file without a password in Java. I've tried setting javax.net.ssl.keyStorePassword to "" but whatever I do I get the following SSL error:
HTTP transport error: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
All my googling would suggest that the sun implementation will not allow an empty password and of course the keytool won't let you import any certificate without a password for the store.
The Sun API seems to require a password, so you will instead need to add a password to your .p12 file.
This page says that you can do this with openssl by converting the .p12 to a .pem, then converting back to a .p12 (but I have not tried it):
openssl pkcs12 -in cert.p12 -out temp.pem -passin pass: -passout pass:temppassword
openssl pkcs12 -export -in temp.pem -out cert-final.p12 -passin pass:temppassword -passout pass:newpassword
rm -f temp.pem
See also this related question.
Related
I have been provided with:
A private key (-----BEGIN RSA PRIVATE KEY-----)
Intermediate CA cert (-----BEGIN CERTIFICATE-----)
Root CA cert (-----BEGIN CERTIFICATE-----)
SSL connectivity exists and I have proven this successfully using curl;
curl -vv https://thirdparty.service.com --key private.pem --cert cert.crt
However, I wish to establish this SSL connection using Java. Given this, I know I need to import these certificates and key into my Java keystore.
I initially imported the Intermediate and Root CA certs only into my Java keystore but I could not establish a successful SSL connection to the third party service. Based on my curl command, I realised that I need to somehow import the private key into the Java keystore.
I have tried many openssl/keytool commands and this is the current combination/command I have running. I still cannot establish an SSL connection using Java.
cat cert.crt cachain.crt > import.pem
echo "pazzword" > pazzword.txt
openssl pkcs12 -export -in import.pem -inkey privkey.pem -name my_bundle -passout file:pazzword.txt > server.p12
${JAVA_HOME}/bin/keytool -importkeystore -srckeystore server.p12 -destkeystore ${JAVA_HOME}/jre/lib/security/cacerts -srcstoretype pkcs12 -srcstorepass pazzword -deststorepass changeit
Versions:
openjdk version "1.8.0_345"
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
Can someone please help clarify what I should be doing with the certs and key I have above?
A successful SSL connection using my Java
I want to call some web services through an HTTPS connection in Java. The certificate authority gave me a PKCS12 file but I get a
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
due to
javax.net.ssl.SSLHandshakeException
Here is the code I am executing :
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pwd");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "pwd");
System.setProperty("proxySet","true") ;
System.setProperty("https.proxyHost", "XXX") ;
System.setProperty("https.proxyPort", "XXX") ;
I first tried to give the PKCS12 file, then the JKS but I had the same error.
I tried another solution, with curl. So I extracted certificates from the PKCS12 and the requests successed.
Here are the commands that I used to extract the different files from the P12 :
openssl pkcs12 -in file.p12 -nocerts -nodes -out clientcert.key
openssl pkcs12 -in file.p12 -clcerts -nokeys -out clientcert.cer
openssl pkcs12 -in file.p12 -cacerts -nokeys -chain -out cacerts.cer
Am I wrong with the way I use those files in Java ?
PKCS12 normally contains a privatekey and cert (chain) combination, and is used to authenticate your system i.e. the client, which is done with the javax.net.ssl.keyStore* properties. You should specify type PKCS12, although some Java8 versions (only!) can read PKCS12 when you specify JKS.
It typically does NOT authenticate the server(s), which is what javax.net.ssl.trustStore* is for, so don't use it there. Depending on the server(s?), you may or may not need a custom truststore different from the P12 and also different from Java's default.
Look at the cert chain used by the server with a browser or other tool like curl or keytool -printcert -sslserver host[:port]
and determine whether it uses a public root CA like Verisign-now-Symantec-now-Digicert or GoDaddy, which will already be in Java's default truststore, or a 'private' CA or even a self-signed cert, in which case you should either add that cert to the default truststore or if you can't or don't want to modify your JVM put that cert in a keystore file you use as the truststore.
PS: the ValidatorException causes the SSLHandshakeException not the reverse.
I am trying to implement SSL for my sample Spring Boot application. I was given a example.pem, example.key, example.csr, example.crt and a example.p7b file by the admin for example.com.
I converted my PEM to a DER file by using this command:
openssl x509 -outform der -in example.pem -out example.der
Then, I converted the DER file to a JKS file as:
keytool -import -alias example -keystore example.jks -file example.der
Then, I put the JKS file into the main/resources directory and following in the application.properties file:
server.port=443
# SSL settings
server.ssl.enabled=true
server.ssl.key-store=classpath:example.jks
server.ssl.key-store-password=example
server.ssl.key-password=example
Now, when I hit https://example.com or https://example.com:443 (doesn't matter as HTTPS is on 443), I get the following trace:
04:05:10.667 [qtp555826066-15] DEBUG o.e.jetty.server.HttpConnection -
javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478)
...
Did I converted the wrong file to JKS or did I do something wrong?
EDIT:
I use embedded Jetty server.
UPDATE:
When I try to add the key file to pem and get a pkcs12 file using the command:
openssl pkcs12 -export -inkey example.key -in example.pem -name example -out example.pkcs12
I get example.pkcs12 file but also an error saying:
No certificate matches private key
Is my PEM or KEY files corrupted?
I got the CA signed certificates and tried to import into the Oracle Wallet Manager for OHS SSL. Private Key and certificate request is generated using open ssl and so we have to create the pkcs12 cert first using the below -
openssl pkcs12 -export -name myservercert -in selfsigned.crt -inkey server.key -out keystore.p12
After that i converted this to JKS using below -
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert
and then imported the Intermediate certs in the JKS. After that when i am trying to convert jks to pkcs12 again using -
mw_home\oracle_common\bin\orapki wallet jks_to_pkcs12 -wallet ./ -pwd "mypassword" -keystore ./mykeystore.jks -jkspwd "mypassword"
I am getting the error - Exception : java.io.IOException: No self-signed cert in chain.
We are not using any self-signed certificate so wondering from where we are getting this issue.
I tried using the p12 keystore that i created in the very first step but there is no certificate request or certificates getting displayed in Oracle Wallet.
Please suggest what is wrong I am doing or is there any best way to import certificates in Oracle Wallet.
why did you use keytool to import intermediate certifcates and not orapki?
orapki wallet add -wallet -cert trustedcerts.crt -trusted_cert
You don't need to bother creating a JKS file. Oracle wallets are valid PKCS12 files. Just create a PEM file with full certificate chain (your private key, your cert, and the full certificate chain in a single file), then run
openssl pkcs12 -export -in certchain.pem -out ewallet.p12
The name 'ewallet.p12' is important. That is Oracle's requirement. Put this file in your wallet directory, then run
orapki wallet create -wallet . -pwd your_pass -auto_login
to create the cwallet.sso file.
I am coding an application where I control the code of both the client and the server.
I am using SSLSockets to implement it.
I have the protocol already running with normal unsecured sockets, but when I try to switch to SSLSockets (using exactly the same protocol), I keep getting the following stack trace:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:782)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:739)
For some reason, the exact same code works perfectly with unsecured sockets. Why could this be?
Any feedback would be appreciated. Thank you.
Pablo
From your post it is not possile to detect the problem.
When you switch to secure sockets the most secure ciphers are used by default.
If you have not configured your truststore/keystore correctly (or have not enabled the non-authenticated suites) then the SSL handshake will fail.
The exception seems to indicate that.
What you can do is run your program using javax.net.debug=ssl,handshake to enable SSL debugging info and post the debugging info and your code if you expect someone to help you.
Depending on what OS you are using, it may require admin/root priveledges to bind to or listen to the SSL port. Trying running your application with admin rights (in Windows) or sudo'd (on Linux).
Reasons can vary, -Djavax.net.debug=ssl is your friend, as suggested by Vladimir Dyuzhev.
Anyway, it may be a certificate problem -- make sure you have correct keystore and trustore. You will require one entry in keystore with:
private key
certificate
complete chain of issuer of the certificate
And a truststore:
complete chain of certificates for server certificate
I have problems generating proper keystore (trustore is easy -- just use keytool). For keystore you need st like this (Linux with openssl + java):
# convert all to PEM
openssl x509 -in ${ca}.der -inform DER -outform PEM -out ${ca}.pem
openssl x509 -in ${subca}.der -inform DER -outform PEM -out ${subca}.pem
# create one large PEM file containing certificate chain
cat ${ca}.pem ${subca}.pem > tmp_cert_chain.pem
# generate PKCS#12 BUNDLE
openssl pkcs12 -export -in ${cert}.pem -inkey ${key}.pem -certfile tmp_cert_chain.pem -out tmp_pkcs12.pfx
# convert PKCS#12 bundle to JKS
keytool -importkeystore -srckeystore tmp_pkcs12.pfx -srcstoretype pkcs12 -srcstorepass ${storepass} -destkeystore $keystore -deststoretype jks -deststorepass ${storepass}
# print out JKS keystore
keytool -list -keystore $keystore -storepass $storepass