I have created a 开发者_JS百科standalone executable JAR program that needs to send private information over a SSL connection.
I was not able to establish the SSL connection using certificates. Was getting this: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`
So I found some code somewhere that creates a trust manager that does not validate certificate chains:
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
That did the trick and I was able to establish SSL connection without any certificates.
My concern is if the data will still be encrypted when exchanging private information. This is an execute JAR file that clients will be downloading to their computers.
So is a certificate really necessary for this case?
It's still encrypted BUT not trustworthy. Best to fix the certificate validation issues instead.
Essentially, SSL provides both encryption and a trust mechanism. You're bypassing the trust part, so the message will still be encrypted, but prone to interception or snooping, using, e.g., a man-in-the-middle attack. A MITM could intercept the request, and complete the SSL handshake using a completely different certificate. They could optionally forward your message to the intended server & back, so you'd never know the message was intercepted.
You should look at downloading the server certificate and putting it into a truststore, which can be loaded at runtime.
See keytool. The keytool executable comes bundled with the JDK, and you can use this command-line tool to create a 'keystore' (in this case, known as a 'truststore'), and import a certificate into it.
There are many ways to tell Java to use a keystore, and your choice depends on what libraries etc you're using to make the SSL connection. One method is to use startup options, e.g.:
-Djavax.net.ssl.trustStore=mySrvKeystore -Djavax.net.ssl.trustStorePassword=123456
Best to google for "keystore java" plus your library name (if you're using one)
HTH
With such a trust manager (or with anonymous cipher suites), the connection will still be encrypted (assuming you're not enabling a cipher suite that use a null cipher, which should never be enabled by default).
However, the client won't know with which entity it is exchanging secret information: it could be a Man-In-The-Middle attacker.
Encryption isn't enough: you need to know who you're talking to. The client needs to verify that:
- it trusts the server certificate to be genuine (that's the purpose of the trust manager, but not this particular implementation since it never rejects anything),
- this certificate is valid for the host name the client intended to contact.
精彩评论