How to use SSL with a self-signed certificate in groovy? - ssl

I have some resources I must access with SSL that use self-signed certificates. In general, most tools have a simple setting to allow these to be accessed without error or just a warning. However, it seems like the proper way to do this with the JVM is to import the signing certificate into a keystore as a CA.
I have a groovy script I'd like to use, but I'd prefer my script to work standalone on any any JVM without modifying the keystore or distributing a new keystore. Is there a simple way to override the certification verification?

After a bit of research, I found this post. Here's what I ended up using:
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
def nullTrustManager = [
checkClientTrusted: { chain, authType -> },
checkServerTrusted: { chain, authType -> },
getAcceptedIssuers: { null }
]
def nullHostnameVerifier = [
verify: { hostname, session -> true }
]
SSLContext sc = SSLContext.getInstance("SSL")
sc.init(null, [nullTrustManager as X509TrustManager] as TrustManager[], null)
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
HttpsURLConnection.setDefaultHostnameVerifier(nullHostnameVerifier as HostnameVerifier)
Use at your own risk: this subverts certificate verification!

i just had to go thru this with a grails app i am working on. You will only deal with the keystore once. Assuming you have the cert, just put it into your keystore, then point your jvm at the keystore via command line props...
edit - i dont know of any way to bypass the need for the keystore. But you can create one with just the cert(s) you need and pass it around with your app. You only do it once.
edit edit -- here is the command for the keytool and the java CL prop
keytool -import -trustcacerts -alias www.the-domain.com -file the-cert.der -keystore store.jks
-Djavax.net.ssl.trustStore=/path/to/store.jks

Related

How to solve this error in my local machine?

Could not create script recorder - see log for details: >> keytool error: java.secuirity.KeyStoreException: jks not found <<
Command failed, code: 1
'keytool -genkeypair - alias : root_ca:-dname "CN= _JMeter Root for CA for recording (INSTALL ONLY IF IT S YOURS ), OU= Username: ujala , C=IN" -keyalg RSA -keystore proxyserver .jks -storepass {redacted}-keypass {redacted}-validity 7 - ext bc:c'
How to solve this error during the recording controller in JMeter???
If you properly installed JMeter and Java you should not see error like this, at least I have never faced anything similar.
The fact that keytool application cannot detect jks keystore type which is the default type indicates that something is wrong with your Java installation so I would recommend reinstalling JDK from scratch.
My expectation is that it should resolve your issue. If it doesn't - check whether you (or somebody else) amended any default Test Script Recorder certificate configuration. If the values differ from defaults - try reverting them (or even reinstalling JMeter)
Also be aware of an alternative way of recording a JMeter test: JMeter Chrome Extension, in this case you won't need to think about proxies and certificates

Karate - Not able to establish connection with pkcs12 keystore and password

I am not able to establish connection with pkcs12 keystore and password. I have a crt certificate and key file for the same. Converted the same to PFX using openssl and followed the instructions as per the link https://github.com/intuit/karate#x509-certificate-authentication. Still facing timeout issues. I try with crt and key file in postman settings, it does work.
* configure ssl = { keyStore: 'classpath:sdfnon-prod.pfx', keyStorePassword: '*****', keyStoreType: 'pkcs12' }
Can you please suggest me, if there is something else that needs to be configured.
Most likely a proxy is involved, please see these answers: https://stackoverflow.com/search?q=%5Bkarate%5D+ssl+proxy
I experienced a similar issue until a figured that the line
* configure ssl = { trustAll: true }
should go above the
* configure ssl = {...}
line in a feature file
Is interesting to me that adding the ssl info into the karate-config.js didn't need the trustAll flag set

Gradle use certificate authentication for repository

The Problem
I have a Android Gradle project which should pull a lib from my companys sonatype nexus server. The nexus server uses a certificate authentication. That means the client has a private certificate which authenticates and authorizes him against the nexus server.
The problem is how to configure gradle to use my certificate (which is in the osx keystore).
/app/build.gradle
repositories {
// some other repositorys...
...
maven {
credentials {
username = NEXUS_USERNAME
password = NEXUS_PASSWORD
}
url 'https://prefix.server.com/nexus/content/repositories/artifactid'
}
}
Without giving a certificate the nexus server respont with:
Error: Could not HEAD 'https://prefix.server.com/nexus/content/repositories/artifactid/de/komoot/android/kmt-material-showcase/0.0.1/kmt-material-showcase-0.0.1.pom'. Received status code 400 from server: Bad Request
My first solution was to try to configure the jvm to use the osx keychain for certificates. The same method helped me to push and publish libs/artifacts on the nexus server.
/app/gradle.properties
org.gradle.jvmargs=-Djavax.net.ssl.keyStore=NONE -Djavax.net.ssl.keyStoreType=KeychainStore -Djavax.net.ssl.keyStorePassword=-
This doesn't work the gradle sync failed:
Error:NONE (No such file or directory)
It looks like the gradle expected to be 'NONE' of the paramter '-Djavax.net.ssl.keyStore'. I tryed several uper and lower case solutions but all failed.
The second approach was to try it with
org.gradle.jvmargs=-Djavax.net.ssl.keyStoreType=KeychainStore
But the server respond with 400 again. Looks like the JVM args haven't been used.
Any ideas or articles for this topic ?
Hope someone can help me.
The Problem was that the Java process didn't have the certificate for authentication.
In my first approach I came very close but I forgot to add the company's root CA cert. My company's private certificate belongs to the root CA, so both must be provided to java.
Solution:
First provide your private company certificate to the gradle process.
Edit your user gradle.properties and add
org.gradle.jvmargs=-Djavax.net.ssl.keyStore="/Users/myusername/certificates/my_private_company_cert.p12" -Djavax.net.ssl.keyStoreType=KeychainStore -Djavax.net.ssl.keyStorePassword=changeit
Then export your company's root ca cert to the java keystore.
sudo keytool -import -trustcacerts -alias root -file ./certificates/company_root_ca.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
Thats it certificate authentication should now work.
This is used for example to make own android libary projects and push them to a artifact server.
https://medium.com/android-news/the-complete-guide-to-creating-an-android-library-46628b7fc879#.naboz7yng
My solution was by updating the ca certificates on the ubuntu/debian system.
update-ca-certificates -f

Certificate chaining error in Websphere

I am trying to consume a RESTful service from url https://someurl.com.
I have added the following properties in my code:
Security.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");
Security.setProperty("ssl.ServerSocketFactory.provider", "com.ibm.jsse2.SSLServerSocketFactoryImpl");
Security.setProperty("javax.net.ssl.trustStore", "cacerts.jks");
Security.setProperty("javax.net.ssl.keyStore", "keystore.jks");
Security.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
Security.setProperty("javax.net.ssl.trustStoreType", "JKS");
The configuration changes that I have done so far are:
set com.ibm.websphere.ssl.retrieveLeafCert to true
retrieved the certificate using url as someurl and port 443 and added it to the truststore.
restarted the server
But I am getting the following exception:
java.security.cert.CertPathValidatorException: Certificate chaining error
javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is:
java.security.cert.CertPathValidatorException: The certificate issued by CN=Walmart Root CA, O=Wal-Mart Stores Inc is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
at com.ibm.jsse2.o.a(o.java:22)
at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:423)
at com.ibm.jsse2.kb.a(kb.java:192)
at com.ibm.jsse2.kb.a(kb.java:176)
at com.ibm.jsse2.lb.a(lb.java:53)
at com.ibm.jsse2.lb.a(lb.java:464)
at com.ibm.jsse2.kb.s(kb.java:545)
at com.ibm.jsse2.kb.a(kb.java:530)
at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:79)
at com.ibm.jsse2.SSLSocketImpl.h(SSLSocketImpl.java:437)
at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:142)
at com.ibm.jsse2.SSLSocketImpl.startHandshake(SSLSocketImpl.java:686)
at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:98)
at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:13)
at com.ibm.net.ssl.www2.protocol.https.b.connect(b.java:6)
at com.dwl.tcrm.tester.RESTClient_2.main(RESTClient_2.java:76)
I'm assuming you have a web application, which is trying to access that restful service.
First, you should not set your stores via javax.net.ssl.* properties, but use SSL configurations provided in WebSphere. So comment all these setProperty() calls.
Second, you have to add your service server certificate to the trust store.
Login to web admin console:
Go to Security > SSL certificate and key management > Key stores and certificates > NodeDefaultTrustStore > Signer certificates
Click Retrieve from port button, and specify hostname, 443 port, and Alias.
Click Retrieve singer information button.
Verify, if correct certificate is imported (parent).
Save, and restart.
In some versions, the child certificate was imported (not the root), in that case, you will have to manually download the root certificate and intermediate (e.g. via browser, and import that one to the NodeDefaultTrustStore, but this time using Add button, not Retrieve..
This means your certificate is not added in cacerts. Try to execute this command as
keytool -list -v -keystore your_path_to_cacerts (Provide the list of cert in cacerts)
check by matching the serial number of your certificate. If it is not there then please follow the steps given below
To export the Intermediate certificate: Internet Explorer -> Tools -> Internet Options -> Content -> Certificates ->
To view the Certificate Path: Select Certificate -> View -> Certification Path ->
To Export the Certificate: Select Certificate -> Export -> DER
encoded Binary Format -> Save ( From Firefox -> Tools -> Options -> Advanced -> Encryption -> View Certificates )
(Given here - http://www-01.ibm.com/support/docview.wss?uid=swg21592616) after this add this exported certificate with below command
keytool -import -trustcacerts -Keystore CACERTS(path) -alias alias -file cert path export in step 3
My issue was the same and I am able to resolve it by following these steps

Coldfusion: CFHTTP with SSL encrypted Page (https://) - got an error

I'm making an cfhttp to connect to an encrypted page. Seems to work fine for some sites.
I/O Exception: Name in certificate `pro.test.com' does not match host name `go.test.com'
Is there a workaround to trust this certificate even if the host name doesn't match?
Think this is more Java question, and workaround should be affecting the JRE.
Not sure if this will work in your case, but possible solution is to import this certificate into the JRE keystore.
Generic description can be found at Sun website. Though process is pretty simple.
First you should navigate the needed HTTPS URL with your browser and export the cert using SSL properties (don't remember how it is done in IE, but in Firefox something like Security > View cert > Details > Save as -- still not sure because using non-English licalization), any X.509 type should work.
Next you should import it using keytool. Navigate to the current CF JRE's bin, execute the following command (replace arguments with your values) and restart CF:
keytool -keystore <path to keystore> -import -file <path to certificate> -alias <alias>
BTW, there is a UI tool for this, but I haven't used it so can't say if it works fine.
The sites that are probably working have a valid SSL Certificate from a trusted authority.
If you have control of pro.test.com, the preferred answer would be to get a valid cert for pro.test.com installed. But if that is not possible for some reason, I see two other options:
1) Do a try/catch where you try to connect via https, and fall back on http in the event of an SSL error. Obviously this would eliminate encryption for the failed connection.
or
2) Use Sergii's solution to import the key for that site into the Java keystore.
If go.test.com is just a development server, in that case you can create a self-signed certificate and import it into Java keystore. That way you can save up on cost by not paying to CA and get a quicker turnaround to resolve the issue