- Saved searches
- Use saved searches to filter your results more quickly
- reflexdemon/java-ssl-test
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- Пример клиентского HTTPS соединения с проверкой серверного сертификатаs
- Java SSL certificate revocation check
- If you certificate contains OCSP link
- If your certificate does not contain OCSP link
- Technical details
- Useful links
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Simple Java based CLI Tool to test SSL connection and list the ciphers
reflexdemon/java-ssl-test
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
This is a CLI utility that is used to test the connectivity between your JDK/JRE to an SSL endpoint. This outputs SSL information like the Ciphers, Protocol, prints Certificate details and it is fully customizable using CLI. This is based upon ssltest. Unlike, ssltest, this is multi threaded and is supposed to be 10x times faster to produce results.
Usage: javassltest [opts] host[:port] Options: -sslprotocol Sets the SSL/TLS protocol to be used (e.g. SSL, TLS, SSLv3, TLSv1.2, etc.) -enabledprotocols protocols Sets individual SSL/TLS ptotocols that should be enabled -ciphers cipherspec A comma-separated list of SSL/TLS ciphers -keystore Sets the key store for connections (for TLS client certificates) -keystoretype type Sets the type for the key store -keystorepassword pass Sets the password for the key store -keystoreprovider provider Sets the crypto provider for the key store -truststore Sets the trust store for connections -truststoretype type Sets the type for the trust store -truststorepassword pass Sets the password for the trust store -truststorealgorithm alg Sets the algorithm for the trust store -truststoreprovider provider Sets the crypto provider for the trust store -crlfilename Sets the CRL filename to use for the trust store -check-certificate Checks certificate trust (default: false) -no-check-certificate Ignores certificate errors (default: true) -verify-hostname Verifies certificate hostname (default: false) -no-verify-hostname Ignores hostname mismatches (default: true) -showsslerrors Show SSL/TLS error details -showhandshakeerrors Show SSL/TLS handshake error details -showerrors Show all connection error details -hiderejects Only show protocols/ciphers which were successful -showcerts Shows some basic Certificate details -h -help --help Shows this help message -v -version --version Shows the version information and exists
To make the distribution seamless, we have used Node Package Manager (NPM) based approach. That will require you to install the application using NPM.
Runs on any platform that supports requirements including Mac, Windows, and Linux.
To install the CLI tool just run the following command.
Troubleshooting on Permissions
If you are running into permission issues on installing global application please refer to this link. https://docs.npmjs.com/getting-started/fixing-npm-permissions
One of the known issue is some of the node versions that do not work and throws errors. In that case please consider the following,
Downgrade the Node Version to the previous stable LTS (Long Term Support) version of nodejs.
- Install NVM: https://github.com/creationix/nvm/blob/master/README.md#installation
- Install the stable version of nodjs using: nvm install v8.11.1
- Install your cli tool: npm i -g
The other issue could be your JDK or JRE are conflicting on the path and that is causing the mixed runtime and Java SSL API is not able to use the correct runtime values.
On linux/unix based systems,
export JAVA_HOME= export PATH=$JAVA_HOME/bin:$PATH
set JAVA_HOME= set PATH=%JAVA_HOME%\bin;%PATH%
If the above options did not help and you wish to report issues please visit https://github.com/reflexdemon/java-ssl-test/issues and log your issues with the following details,
- java -version output
- javac -version output
- npm -v output
- node -v output
To make this happen I will have to thank the below people and their creations.
Пример клиентского HTTPS соединения с проверкой серверного сертификатаs
Т.о. проведен эксперимент с простейшей односторонней аутентификацией. Недостаток вышеприведенного кода очевиден. В нем применен TrustManager не проверяющий подлинность сервера. Такой код в некоторых случаях достаточен. Но в большинстве — нет. Следующим экспериментом используем нормальный TrustManager с проверкой серверного сертификата. Для этого надо создать truststore с серверным сертификатом. Ищу документацию и нахожу Generating a Keystore and Truststore. Из документа следует, что для создания truststore, нужно с помощью keytool импортировать в него сертификат. Для этого сертификат нужно сначала экспортировать. Делается это следующей командой:
keytool -export -keystore server.jks -alias server-test -storepass storepass -file server.cer
В итоге получается файл server.cer с сертификатом сервера. Теперь создаю на его основе truststore:
keytool -import -keystore clienttrust.jks -file server.cer -storepass storepass
В итоге получаю clienttrust.jks. Ниже на картинке дерево maven-овского проекта. Keystore и truststore лежат в директории resources.
Добавляю в код клиента код читающий и задающий truststore для соединения. Ниже читается keystore с именем clienttrust.jks из ресурсов. Создается TrustManagerFactory на основе keystore.
char[] passphrase = "storepass".toCharArray(); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(this.getClass().getResourceAsStream("clienttrust.jks"), passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks);
Тестирую измененный клиент. Он работает. Серверный сертификат проходит проверку. Т.о. ниже клиентский код для односторонней аутентификации, осуществляющий проверку серверного сертификата по truststore:
import com.sun.net.httpserver.\*; import org.junit.Test; import javax.net.ssl._; import java.io._; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.security.\*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class SimpleServerTest static class MyHandler implements HttpHandler public void handle(HttpExchange t) throws IOException String response = "This is the response"; t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); > > void startServer(int port) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, InterruptedException, KeyManagementException HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 5); server.createContext("/", new MyHandler()); char[] storepass = "storepass".toCharArray(); char[] keypass = "serverpass".toCharArray(); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(SimpleServerTest.class.getResourceAsStream("server.jks"), storepass); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, keypass); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), new TrustManager[]<>, null); server.setHttpsConfigurator(new HttpsConfigurator(sslContext) public void configure (HttpsParameters params) // get the remote address if needed InetSocketAddress remote = params.getClientAddress(); SSLContext c = getSSLContext(); // get the default parameters SSLParameters sslparams = c.getDefaultSSLParameters(); params.setSSLParameters(sslparams); // statement above could throw IAE if any params invalid. // eg. if app has a UI and parameters supplied by a user. > >); server.setExecutor(null); // creates a default executor server.start(); > @Test public void testClientWithTrustStore() throws CertificateException, InterruptedException, UnrecoverableKeyException, NoSuchAlgorithmException, IOException, KeyManagementException, KeyStoreException startServer(8080); URL url = new URL("https://localhost:8080/"); HttpsURLConnection con = (HttpsURLConnection)url.openConnection(); con.setRequestMethod( "GET" ); SSLContext sslContext = SSLContext.getInstance("TLS"); char[] passphrase = "storepass".toCharArray(); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(this.getClass().getResourceAsStream("clienttrust.jks"), passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); HostnameVerifier hostnameVerifier = new HostnameVerifier() public boolean verify(String s, SSLSession sslSession) return s.equals(sslSession.getPeerHost()); > >; con.setHostnameVerifier(hostnameVerifier); sslContext.init(null, tmf.getTrustManagers(), null); con.setSSLSocketFactory(sslContext.getSocketFactory()); int responseCode = con.getResponseCode(); InputStream inputStream; if (responseCode == HttpURLConnection.HTTP_OK) inputStream = con.getInputStream(); > else inputStream = con.getErrorStream(); > // Process the response BufferedReader reader; String line = null; reader = new BufferedReader( new InputStreamReader( inputStream ) ); while( ( line = reader.readLine() ) != null ) System.out.println( line ); > inputStream.close(); > >
Т.о. протестировано соединение с односторонней аутентификацией в двух вариантах: без аутентификации сервера и c аутентификацией сервера.
Взято:
https://dev64.wordpress.com/2013/06/18/configure-embedded-jdk-http-server-for-https/
Tags: Пример клиентского HTTPS соединения с проверкой серверного сертификата
Java SSL certificate revocation check
There is two common way to check TLS certificate revocation status:
The second option is more faster and modern way to do that. The OCSP link must be presented some way to do that. There are at least two options:
- Your Certificate Authority (CA) automatically puts that OCSP link into your certificate
- You go to the guys in your CA and asks them for the OCSP link.
There is how you can check if your SSL certificate contains OCSP link:
- If you don’t see OCSP link in first point, you must scroll down information into this section to the second point
If you certificate contains OCSP link
- Add -Dcom.sun.net.ssl.checkRevocation=true flag when you run your jar
- Set Security property from inside your code: java.security.Security.setProperty(«ocsp.enable», «true»)
After you perform this, every time Java sees new TLS connection, it is going to OCSP CA server through the link from AIA section of TLS certificate, check the revocation status, and reject the connection if certificate was revoked.
If your certificate does not contain OCSP link
- Add -Dcom.sun.net.ssl.checkRevocation=true flag when you run your jar
- Set Security property from inside your code: java.security.Security.setProperty(«ocsp.enable», «true»)
- Go to the guys from your CA and asks them for OCSP link
- Set one more Security property inside your code: Security.setProperty(«ocsp.responderURL», url)
P.S.: there might be one case, when OCSP server itself has specific SSL cert. If so, you need to set other Security properties manually:
- Security.setProperty(«ocsp.responderCertSubjectName», certSubjectName)
- Security.setProperty(«ocsp.responderCertIssuerName», certIssuerName)
- Security.setProperty(«ocsp.responderCertSerialNumber», certSerialNumber)
Technical details
If you interested in how this works under the JVM hood, you might want to see this classes:
java.security.cert.PKIXRevocationChecker, class declaration is: public abstract class PKIXRevocationChecker extends PKIXCertPathChecker
sun.security.provider.certpath.RevocationChecker, class declaration is: class RevocationChecker extends PKIXRevocationChecker
You can navigate into sun.security.provider.certpath.RevocationChecker class just by pasting this line into IntelliJ IDEA and clicking on the class name with CTL+left click ignoring error (red glow).
You can see, how RevocationChecker class reads Security properties in method:
private static RevocationProperties getRevocationProperties()
Useful links
If you still have any questions, feel free to ask me in the comments under this article, or write me on promark33@gmail.com.