Java:覆盖功能以禁用 SSL 证书检查
2022-09-01 11:45:34
Web 服务通过 SSL 进行休息,并且具有托管在远程系统中的自签名证书。我已经创建了一个访问该Web服务的客户端。这是通过以编程方式将证书添加到密钥存储来完成的。
现在我听说,没有必要将证书添加到密钥存储区以访问自签名Web服务。相反,我们可以通过覆盖某些方法来禁用证书检查。这是真的吗?这些方法有哪些?请帮忙。
Web 服务通过 SSL 进行休息,并且具有托管在远程系统中的自签名证书。我已经创建了一个访问该Web服务的客户端。这是通过以编程方式将证书添加到密钥存储来完成的。
现在我听说,没有必要将证书添加到密钥存储区以访问自签名Web服务。相反,我们可以通过覆盖某些方法来禁用证书检查。这是真的吗?这些方法有哪些?请帮忙。
这应该足够了。在针对没有正确签名的证书的测试和暂存服务器测试代码时,我使用它。但是,您应该非常强烈地考虑在生产服务器上获取有效的SSL证书。没有人希望被窃听并侵犯他们的隐私。
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new TrustAllX509TrustManager() }, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier(){
public boolean verify(String string,SSLSession ssls) {
return true;
}
});
还有这个。
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
/**
* DO NOT USE IN PRODUCTION!!!!
*
* This class will simply trust everything that comes along.
*
* @author frank
*
*/
public class TrustAllX509TrustManager implements X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
}
}
祝你好运!
===更新===
我只是想指出,有一个名为Let's Encrypt的服务,它自动化了生成和设置几乎每个人都认可的SSL / TLS证书的过程,而且它是完全免费的!
基于每个连接忽略证书要安全得多,因为任何其他代码仍将使用安全默认值。
下面的代码:
正如其他人所说,这应该仅用于测试和/或与其他内部系统通信的内部系统。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class TestPersistentConnection
{
private static SSLSocketFactory sslSocketFactory = null;
/**
* Use the VM argument <code>-Djavax.net.debug=ssl</code> for SSL specific debugging;
* the SSL handshake will appear a single time when connections are re-used, and multiple
* times when they are not.
*
* Use the VM <code>-Djavax.net.debug=all</code> for all network related debugging, but
* note that it is verbose.
*
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
//URL url = new URL("https://google.com/");
URL url = new URL("https://localhost:8443/");
// Disable first
request(url, false);
// Enable; verifies our previous disable isn't still in effect.
request(url, true);
}
public static void request(URL url, boolean enableCertCheck) throws Exception {
BufferedReader reader = null;
// Repeat several times to check persistence.
System.out.println("Cert checking=["+(enableCertCheck?"enabled":"disabled")+"]");
for (int i = 0; i < 5; ++i) {
try {
HttpURLConnection httpConnection = (HttpsURLConnection) url.openConnection();
// Normally, instanceof would also be used to check the type.
if( ! enableCertCheck ) {
setAcceptAllVerifier((HttpsURLConnection)httpConnection);
}
reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()), 1);
char[] buf = new char[1024];
StringBuilder sb = new StringBuilder();
int count = 0;
while( -1 < (count = reader.read(buf)) ) {
sb.append(buf, 0, count);
}
System.out.println(sb.toString());
reader.close();
} catch (IOException ex) {
System.out.println(ex);
if( null != reader ) {
reader.close();
}
}
}
}
/**
* Overrides the SSL TrustManager and HostnameVerifier to allow
* all certs and hostnames.
* WARNING: This should only be used for testing, or in a "safe" (i.e. firewalled)
* environment.
*
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
protected static void setAcceptAllVerifier(HttpsURLConnection connection) throws NoSuchAlgorithmException, KeyManagementException {
// Create the socket factory.
// Reusing the same socket factory allows sockets to be
// reused, supporting persistent connections.
if( null == sslSocketFactory) {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, ALL_TRUSTING_TRUST_MANAGER, new java.security.SecureRandom());
sslSocketFactory = sc.getSocketFactory();
}
connection.setSSLSocketFactory(sslSocketFactory);
// Since we may be using a cert with a different name, we need to ignore
// the hostname as well.
connection.setHostnameVerifier(ALL_TRUSTING_HOSTNAME_VERIFIER);
}
private static final TrustManager[] ALL_TRUSTING_TRUST_MANAGER = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
private static final HostnameVerifier ALL_TRUSTING_HOSTNAME_VERIFIER = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
}
非常感谢: http://runtime32.blogspot.com/2008/11/let-java-ssl-trust-all-certificates.html