Web服務是通過SSL進行的休眠,它具有自簽名證書,託管在遠程系統中。我已經創建了訪問該Web服務的客戶端。這是通過將證書添加到key store programatically來完成的。Java:覆蓋功能以禁用SSL證書檢查
現在我聽說,沒有必要向密鑰存儲區添加證書以訪問自簽名的Web服務。 相反,我們可以通過重寫某些方法來禁用證書檢查。這是真的?哪些是這些方法?請幫忙。
Web服務是通過SSL進行的休眠,它具有自簽名證書,託管在遠程系統中。我已經創建了訪問該Web服務的客戶端。這是通過將證書添加到key store programatically來完成的。Java:覆蓋功能以禁用SSL證書檢查
現在我聽說,沒有必要向密鑰存儲區添加證書以訪問自簽名的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) {
}
}
祝你好運!
=== UPDATE ===
我只是想指出的是,有一個名爲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
你是否確定它在每個連接的基礎上工作?使用'SSLContext.getInstance'我永遠不知道它是吸氣劑還是什麼... – maaartinus
相當確定。在示例程序中唯一的替換是enableCertCheck爲false(通過setAcceptAllVerifier(...))。如果系統範圍的套接字工廠和主機名驗證器被替換,則第二次調用main()中的request(url,true)會在標準輸出上打印一個異常。否則,它將被改變的唯一方式是暫時通過連接本身,這將在它完成後恢復它,這看起來不太可能。 –
這個工程!我有用於禁用證書檢查的'setDefaultSSLSocketFactory'版本,但它使我到另一個網站的其他連接確實需要證書檢查失敗。我只是適應了這一點,現在我可以連接到兩個https站點 – jpp1jpp1
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
GetCustomerPhone http = new GetCustomerPhone();
System.out.println("Processing..");
try{
http.sendPost();
}
catch(Exception e){
e.printStackTrace();
}
}
我認爲它會工作fine.because它我的罰款...
Web服務不應該有一個自簽名的證書。期。支付這筆費用並由CA簽署。你所聽到的確是正確的,但它也是非常不可取的。它需要在客戶端進行特殊編程,這會引入(a)安全問題,(b)發展風險和(c)部署問題。 – EJP
該Web服務尚未發佈。它正在工作。這就是爲什麼現在它沒有通過可信CA認證。已知通過禁用這些證書檢查來使用服務是不理想的。儘管我需要檢查它。請幫忙。謝謝@EJP – Sumithlal
爲臨時解決方案花費的任何努力(a)浪費時間和金錢,(b)引入安全風險,即您將「意外」部署到生產環境中。現在花錢。只有幾百美元。 – EJP