-
-
Save 4ndrej/4547029 to your computer and use it in GitHub Desktop.
import javax.net.ssl.SSLParameters; | |
import javax.net.ssl.SSLSocket; | |
import javax.net.ssl.SSLSocketFactory; | |
import java.io.*; | |
/** Establish a SSL connection to a host and port, writes a byte and | |
* prints the response. See | |
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services | |
*/ | |
public class SSLPoke { | |
public static void main(String[] args) { | |
if (args.length != 2) { | |
System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>"); | |
System.exit(1); | |
} | |
try { | |
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); | |
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1])); | |
SSLParameters sslparams = new SSLParameters(); | |
sslparams.setEndpointIdentificationAlgorithm("HTTPS"); | |
sslsocket.setSSLParameters(sslparams); | |
InputStream in = sslsocket.getInputStream(); | |
OutputStream out = sslsocket.getOutputStream(); | |
// Write a test byte to get a reaction :) | |
out.write(1); | |
while (in.available() > 0) { | |
System.out.print(in.read()); | |
} | |
System.out.println("Successfully connected"); | |
} catch (Exception exception) { | |
exception.printStackTrace(); | |
System.exit(1); | |
} | |
} | |
} |
Very useful thanks.
A note however, instead of updating the java JRE/JDK installation's keystore, best practices dictates that you should define your own truststore (if you have company CA or application certificates for example):
# import certificate into your local TrustStore
keytool -import -trustcacerts -storepass changeit -file "./class 1 root ca.cer" -alias C1_ROOT_CA -keystore ./LocalTrustStore
# use it in JAVA:
java -Djavax.net.ssl.trustStore=./LocalTrustStore -jar SSLPoke.jar $HOST $PORT
Will the default trustStore be overwritten by -Djavax.net.ssl.trustStore
or is the new trustStore an addition to the default one? @Tzaphkiel
Thanks for sharing. When I try the negative test , I have the exception :
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1708)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1691)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1617)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:105)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:114)
at SSLPoke.main(SSLPoke.java:23)
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at com.sun.net.ssl.internal.ssl.DHCrypt.(DHCrypt.java:114)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:559)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:186)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:943)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:654)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:100)
... 2 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
at com.sun.net.ssl.internal.ssl.DHCrypt.(DHCrypt.java:107)
Any idea why I have this ? Another thing can you tell me how I can generate a certificate file from a server ?
@jmara -Djavax.net.ssl.trustStore
will override the default truststore (cacerts). You can copy the default one and then add your cert and set it via -Djavax.net.ssl.trustStore
so you don't lose the default CAs.
Works well! Thanks
P.S. If you don't use the default keystore, you'll need to pass it and the password for the keystore into your command as arguments.
Thanks guys, these steps helped me debug why a couple of Atlassian products couldn't talk to each other. I got it working for now, but in my "ideal" world since every release of an Atlassian product includes it's own JRE, I will automate the above steps into a script to inject the "peer" applications' (hosted on other servers) certificates into only the "vendored" JRE cacerts to allow them to trust each other and this way I'm not polluting the system but I can link all the applications to each other without a bunch of warnings and failures.
Thanks guys, just a +1 that is helping me debug an SSL issue on Weblogic between AdminServer and NodeManager.
Cheers!
I am having trouble w.r.t local certificate.
$java SSLPoke localwc.in 443
Successfully connected
$ java SSLPoke localwc.in 8443
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
...
$ java -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 SSLPoke localwc.in 8443
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
$ java -Djavax.ssl.trustStore=~/Developer/apache-tomcat-8.0.26/ssl/cacerts SSLPoke localwc.in 8443
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
$ keytool -list -v -keystore ~/Developer/apache-tomcat-8.0.26/ssl/cacerts
##This shows entry for my localhost as localwc.in as
Alias name: localwc.in
Creation date: 2 Mar, 2018
Entry type: trustedCertEntry
.....
I am accessing 8443 via tomcat.
How can I overcome it?
http://portecle.sourceforge.net/ is also a very useful tool for loading and testing the Java Trust Store database
thanks for the tool here my example how I used it:
Compile
C:\IBM\WebSphere\AppServer\java\8.0\bin\javac C:\tools\JavaSSL\SSLPoke.java
run like
C:\IBM\WebSphere\AppServer\java\8.0\jre\bin\java -cp C:\tools\JavaSSL SSLPoke myserver.com 636
run with keystore
C:\IBM\WebSphere\AppServer\java\8.0\jre\bin\java -Djavax.net.ssl.trustStore=C:\IBM\WebSphere\AppServer\profiles\MyAppSrv01\config\cells\MyNode01Cell\nodes\MyNode01\trust.p12 -Djavax.net.ssl.trustStorePassword=mypass123 -Djavax.net.ssl.trustStoreType=pkcs12 -cp C:\tools\JavaSSL SSLPoke myserver.com 636
Successfully connected
Hi and Thanks! What's the license of this gist? I noticed https://github.com/MichalHecko/SSLPoke which has Apache, but you are the author?
@simonredfern: the code was shamelessly stolen from Atlassian support , there were no license in code or on the site, just code drop.
I found another link to the code https://confluence.atlassian.com/display/JIRA052/Connecting+to+SSL+services which states "Except where otherwise noted, content in this space is licensed under a Creative Commons Attribution 2.5 Australia License".
I built an online ssl trust checker online
https://www.nmmapper.com/troubleshooting/tools/ssl-trust-checker/online/
It did not work for me.
I always get Successfully connected msg
me too.
I just ran across this and had a similar complaint that it isn't validating the hostname. Fortunately it's an easy fix to add SSLParamters
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
/** Establish a SSL connection to a host and port, writes a byte and
* prints the response. See
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
*/
public class SSLPoke {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>");
System.exit(1);
}
try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
SSLParameters sslparams = new SSLParameters();
sslparams.setEndpointIdentificationAlgorithm("HTTPS");
sslsocket.setSSLParameters(sslparams);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();
// Write a test byte to get a reaction :)
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Successfully connected");
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
I just ran across this and had a similar complaint that it isn't validating the hostname. Fortunately it's an easy fix to add SSLParamters
Merged. Thanks, Steve!
And System.exit(1);
in catch would be fantastic as I use this within CI and rely on the return code.
And
System.exit(1);
in catch would be fantastic as I use this within CI and rely on the return code.
thanks for your suggestion, done.
@dadez Better late than never, here's an updated version from tthe original code with proxy support :
https://gist.github.com/bric3/4ac8d5184fdc80c869c70444e591d3de
@dadez Better late than never, here's an updated version from tthe original code with proxy support :
https://gist.github.com/bric3/4ac8d5184fdc80c869c70444e591d3de
thanks
I made a version that show the current setting of all known (to me) Java properties, which a relevant for TLS:
https://github.com/klasen/sslpoke
Gives error: "Error: Could not find or load main class sslpoke" (I also tried SSLPoke on the command line)
Yeah, I don't do Java, so it looks good to me, and I want to add a --Look_in_the_dang_file to tell it to not be an idiot and look in the file for the class, it is right there, static main... I just copied the 'raw' and then pasted it into a file and ran it with java SSLPoke site.name.com 8693
Hi @traderhut,
expecting you are running this in the same folder the SSLPoke.java is it seems like you are trying to run the source code, not the compiled stuff.
So, run the compiler first:
javac SSLPoke.java
Make sure it produces SSLPoke.class file.
and then run the interpreter:
java SSLPoke site.name.com 8693
@traderhut Also if your Java version is at least JDK 11 you can run the file without compiling it. Just copy the content and paste it into a file name SSLPoke.java
— the .java
extension is important — then run it
$ java -version
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment Corretto-11.0.12.7.2 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.12.7.2 (build 11.0.12+7-LTS, mixed mode)
$ java SSLPoke.java google.com 443
Successfully connected
The error you encounter is probably because you run the following command java sslpoke {site} {port}
. Without the .java
extension the command assumes it is a compiled class. Look at the help.
$ java --help
Usage: java [options] <mainclass> [args...]
(to execute a class)
or java [options] -jar <jarfile> [args...]
(to execute a jar file)
or java [options] -m <module>[/<mainclass>] [args...]
java [options] --module <module>[/<mainclass>] [args...]
(to execute the main class in a module)
or java [options] <sourcefile> [args]
(to execute a single source-file program)
...
Been a while since I looked at Java, like about a year after it came out... Thanks for the assistance, turns out I solved the problem without using this tool
fyi, I use this with this CLI:
java -Djavax.net.ssl.trustStore=/path/to/store/LdapSSLKeyStore.jks -Djavax.net.ssl.trustStorePassword=123 -Djavax.net.ssl.trustStoreType=jks SSLPoke myserver.local 443
#or with debug and force certain protocol
java -Djavax.net.ssl.trustStore=/path/to/store/LdapSSLKeyStore.jks -Djavax.net.ssl.trustStorePassword=123 -Djavax.net.ssl.trustStoreType=jks -Djavax.net.debug=ssl:handshake:verbose -Djdk.tls.client.protocols=TLSv1 -Dhttps.protocols=TLSv1 SSLPoke myserver.local 443
java -Djavax.net.ssl.trustStore=/path/to/store/LdapSSLKeyStore.jks -Djavax.net.ssl.trustStorePassword=123 -Djavax.net.ssl.trustStoreType=jks SSLPoke
Very cool. Exactly what I was looking for. Thanks!
For those not living in the Java World here is how I compiled and used this:
/usr/java/jdk1.6.0_45/bin/javac /tmp/SSLPoke.java
(use your version of Java here)/usr/java/jdk1.6.0_45/bin/java -cp /tmp SSLPoke my-url.com 443