㈠ 如何在Apache HttpClient 4忽略SSL證書錯誤問題,怎麼解決
在訪問部署了SSL證書的網站的過程中,往往由於證書的兼容性、證書配置、證書過期等多種原因提示SSL證書錯誤,這里給大家總結常見的SSL證書錯誤和解決辦法。
ssl證書錯誤一:"無法將這個證書驗證到一個受信任的證書頒發機構"或者類似"該安全證書由您沒有選定信任的公司頒發"等情況。
解決方法:出現的原因可能是由於該證書沒有在瀏覽器信任的列表裡,我們可將該證書安裝到瀏覽器的"信任列表之中即可"具體的步驟是:瀏覽器中選項→內容選項卡→證書-→導入即可。如果是頒發機構不可信的話,推薦購買通過全球認證的SSL證書,比如沃通SSL證書兼容性非常好。
㈡ Java的HttpClient如何去支持無證書訪問https
項目里需要訪問其他介面,通過http/https協議。我們一般是用HttpClient類來實現具體的http/https協議介面的調用。
// Init a HttpClient
HttpClient client = new HttpClient();
String url=http://www.xxx.com/xxx;
// Init a HttpMethod
HttpMethod get = new GetMethod(url);
get.setDoAuthentication(true);
get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
// Call http interface
try {
client.executeMethod(get);
// Handle the response from http interface
InputStream in = get.getResponseBodyAsStream();
SAXReader reader = new SAXReader();
Document doc = reader.read(in);
} finally {
// Release the http connection
get.releaseConnection();
}
以上代碼在通過普通的http協議是沒有問題的,但如果是https協議的話,就會有證書文件的要求了。一般情況下,是這樣去做的。
// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;
if (url.startsWith("https:")) {
System.setProperty("javax.net.ssl.trustStore", "/.sis.cer");
System.setProperty("javax.net.ssl.trustStorePassword", "public");
}
於是,這里就需要事先生成一個.sis.cer的文件,生成這個文件的方法一般是先通過瀏覽器訪問https://,導出證書文件,再用JAVA keytool command 生成證書
# $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer
但這樣做,一比較麻煩,二來證書也有有效期,過了有效期之後,又需要重新生成一次證書。如果能夠避開生成證書文件的方式來使用https的話,就比較好了。
還好,在最近的項目里,我們終於找到了方法。
// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;
if (url.startsWith("https:")) {
this.supportSSL(url, client);
}
用到了supportSSL(url, client)這個方法,看看這個方法是如何實現的。
private void supportSSL(String url, HttpClient client) {
if(StringUtils.isBlank(url)) {
return;
}
String siteUrl = StringUtils.lowerCase(url);
if (!(siteUrl.startsWith("https"))) {
return;
}
try {
setSSLProtocol(siteUrl, client);
} catch (Exception e) {
logger.error("setProtocol error ", e);
}
Security.setProperty( "ssl.SocketFactory.provider",
"com.tool.util.DummySSLSocketFactory");
}
private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception {
URL url = new URL(strUrl);
String host = url.getHost();
int port = url.getPort();
if (port <= 0) {
port = 443;
}
ProtocolSocketFactory factory = new SSLSocketFactory();
Protocol authhttps = new Protocol("https", factory, port);
Protocol.registerProtocol("https", authhttps);
// set https protocol
client.getHostConfiguration().setHost(host, port, authhttps);
}
在supportSSL方法里,調用了Security.setProperty( "ssl.SocketFactory.provider",
"com.tool.util.DummySSLSocketFactory");
那麼這個com.tool.util.DummySSLSocketFactory是這樣的:
訪問https 資源時,讓httpclient接受所有ssl證書,在weblogic等容器中很有用
代碼如下:
1. import java.io.IOException;
2. import java.net.InetAddress;
3. import java.net.InetSocketAddress;
4. import java.net.Socket;
5. import java.net.SocketAddress;
6. import java.net.UnknownHostException;
7. import java.security.KeyManagementException;
8. import java.security.NoSuchAlgorithmException;
9. import java.security.cert.CertificateException;
10. import java.security.cert.X509Certificate;
11.
12. import javax.net.SocketFactory;
13. import javax.net.ssl.SSLContext;
14. import javax.net.ssl.TrustManager;
15. import javax.net.ssl.X509TrustManager;
16.
17. import org.apache.commons.httpclient.ConnectTimeoutException;
18. import org.apache.commons.httpclient.params.HttpConnectionParams;
19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
20.
21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
22. static{
23. System.out.println(">>>>in MySecureProtocolSocketFactory>>");
24. }
25. private SSLContext sslcontext = null;
26.
27. private SSLContext createSSLContext() {
28. SSLContext sslcontext=null;
29. try {
30. sslcontext = SSLContext.getInstance("SSL");
31. sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
32. } catch (NoSuchAlgorithmException e) {
33. e.printStackTrace();
34. } catch (KeyManagementException e) {
35. e.printStackTrace();
36. }
37. return sslcontext;
38. }
39.
40. private SSLContext getSSLContext() {
41. if (this.sslcontext == null) {
42. this.sslcontext = createSSLContext();
43. }
44. return this.sslcontext;
45. }
46.
47. public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
48. throws IOException, UnknownHostException {
49. return getSSLContext().getSocketFactory().createSocket(
50. socket,
51. host,
52. port,
53. autoClose
54. );
55. }
56.
57. public Socket createSocket(String host, int port) throws IOException,
58. UnknownHostException {
59. return getSSLContext().getSocketFactory().createSocket(
60. host,
61. port
62. );
63. }
64.
65.
66. public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
67. throws IOException, UnknownHostException {
68. return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
69. }
70.
71. public Socket createSocket(String host, int port, InetAddress localAddress,
72. int localPort, HttpConnectionParams params) throws IOException,
73. UnknownHostException, ConnectTimeoutException {
74. if (params == null) {
75. throw new IllegalArgumentException("Parameters may not be null");
76. }
77. int timeout = params.getConnectionTimeout();
78. SocketFactory socketfactory = getSSLContext().getSocketFactory();
79. if (timeout == 0) {
80. return socketfactory.createSocket(host, port, localAddress, localPort);
81. } else {
82. Socket socket = socketfactory.createSocket();
83. SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
84. SocketAddress remoteaddr = new InetSocketAddress(host, port);
85. socket.bind(localaddr);
86. socket.connect(remoteaddr, timeout);
87. return socket;
88. }
89. }
90.
91. //自定義私有類
92. private static class TrustAnyTrustManager implements X509TrustManager {
93.
94. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
95. }
96.
97. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
98. }
99.
100. public X509Certificate[] getAcceptedIssuers() {
101. return new X509Certificate[]{};
102. }
103. }
104.
105. }
public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
static{
System.out.println(">>>>in MySecureProtocolSocketFactory>>");
}
private SSLContext sslcontext = null;
private SSLContext createSSLContext() {
SSLContext sslcontext=null;
try {
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslcontext;
}
private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext();
}
return this.sslcontext;
}
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);
}
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port
然後按如下方式使用HttpClient
Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);
Protocol.registerProtocol("https", myhttps);
HttpClient httpclient=new HttpClient();
㈢ HttpClient 怎麼忽略證書驗證訪問https
您好,我來為您解答:
自定義一個SSLSocketFactory,忽略證書的驗證。
如果我的回答沒能幫助您,請繼續追問。
㈣ 怎麼給httpclient 配置https證書
你那個 SSLSocketFactory(ks) 是自己的類?
你有用過 KeyManager.init (...)? 和 TrustManager.init(...) ?
想要在連接建立過程上互動式的彈出確認對話框專來的話需要我們自屬己提供一個 KeyManager 和 TrustManager 的實現類,這有點復雜,你可以看一個 Sun 的 X509KeyManager 是怎麼做的,默認地情況下它是從自動搜索匹配的 subject ,我們需要用自己提供的方式彈出確認的過程還不是全自動,另外一個賬戶可能有多個數字證書,比如支付寶我們就有多個簽發時間不一樣的數字證書,在連接建立時 IE 會提示我們選擇其中的一個來使用,銀行的 U 盾在安裝多張數字證書時也會提示我們選擇其中一個對應到你正在使用的銀行卡號的那張證書。
㈤ 如何處理與Apache HttpClient的無效SSL證書
如果是自己的私有證書,他本身不受信任的,而且可能您的SSL證書缺少了重要的文件,或者可以說不具備
瀏覽器信任條件,可以淘寶Gworg獲取公網信任SSL證書。
㈥ 如何使用HttpClient認證機制
是單向認證還是雙向認證呢?
其實2者實現過程是類似的,我對httpclient4.3+的版本比較熟悉,生成httpclient實例的一般過程是:首先生成SSLContext,然後用sslcontext作為參數傳入工廠方法生成SSLsocketfactory實例,之後通過HttpClientBuilder()將工廠傳進去生成httpclient實例,當然生成工廠實例這一步可以不做,看需求,因為工廠可以設置一些連接參數,如果你用不到可以直接把SSLContext傳入HttpClientBuilder()出來httpclient實例。
過程了解了,那麼如果要做證書驗證,對於單向認證,我們只需要信任伺服器證書即可,如果你手裡有伺服器證書(一般都可以下載),可以直接把它轉成keystore格式,然後sslcontext有一個.loadTrustMaterial(xxx.keystore)方法設置證書信任域,你把伺服器證書設置進去就可以了,還有一個.loadTrustMaterial(null, new TrustSelfSignedStrategy()),這是默認信任所有,當然不太安全,另外還可以通過重寫默認方法信任所有證書,這個不再贅述,你選擇一種方法就行。
對於雙向認證,你只需要把客戶端證書傳過去即可,你手上肯定有客戶端證書對吧,把它整成keystore格式,然後通過sslcontext的.loadKeyMaterial(xx.keystore,"password")把證書傳進去,很簡單吧,下面我給你個例子,是我以前寫的,也參考了網上的例子。
這個是先得到keystore實例
publicclassTrustKey{
@SuppressWarnings("finally")
(){
KeyStoretrustStore=null;
FileInputStreamfis=null;
try{
trustStore=KeyStore.getInstance(KeyStore.getDefaultType());
//fis=newFileInputStream(newFile("D:\java\tomcat8\wx_dev\webapps\data.keystore"));
fis=newFileInputStream(newFile("E:\certi\data.keystore"));
trustStore.load(fis,"password".toCharArray());//載入KeyStore
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(CertificateExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(KeyStoreExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}finally{
try{
fis.close();
}catch(IOExceptione){
e.printStackTrace();
}
returntrustStore;
}
}
下面是生成httpclient實例,用到了連接池,如果你不需要可以去掉。
(){
CloseableHttpClienthttpclient=null;
try{
KeyStoretrustStore=TrustKey.getTrustKey();//獲得keystore
//設置ssl上下文
SSLContextsslContext=SSLContexts.custom()
.loadTrustMaterial(null,newTrustSelfSignedStrategy())
.loadKeyMaterial(trustStore,"sinowel".toCharArray())
.setSecureRandom(newSecureRandom())
.useSSL()
.build();
=PlainConnectionSocketFactory.INSTANCE;
//將參數注入sslconnection工廠,,忽略域名一致驗證
=newSSLConnectionSocketFactory(
sslContext,newString[]{"TLSv1"},null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
//注冊協議
Registry<ConnectionSocketFactory>r=RegistryBuilder.<ConnectionSocketFactory>create()
.register("http",plainSocketFactory)
.register("https",sslSocketFactoy)
.build();
HttpHosttarget=newHttpHost(IP,PORT,"https");
//根據已生成協議工廠對象生成連接管理器
connectionManager=(r);
connectionManager.setMaxTotal(MAXCONNECTION);
//設置每個Route的連接最大數
connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION);
//設置指定域的連接最大數
connectionManager.setMaxPerRoute(newHttpRoute(target),20);
//返回HTTPCLIENT對象
httpclient=HttpClients.custom()
.setConnectionManager(connectionManager)
.setProxy(newHttpHost("10.182.22.88",8002))
.build();
//將ssl上下文及連接管理器注入工廠產生httpclient對象
//=newSSLConnectionSocketFactory(sslContext);
//httpclient=HttpClients.custom().setSSLSocketFactory(sslsf).build();
//httpclient=HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
}catch(Exceptione){
e.printStackTrace();
}finally{
returnhttpclient;
}
}
㈦ Java的HttpClient如何去支持無證書訪問https
Java的HttpClient如何去支持無證書訪問https
SSL 連接的 context 目前用那個 KeyManager, TrustManager 的實現(Sun 公司提供的)都是默認地從命令行提供的參數或代碼中明確初始化的 trust manager / key manager 中查找的,這裡面可以肯定的是這個參數在連接建立之前已經固定了的靜態形式,這要求我們把可以信任的伺服器證書的頒發機構的根證書先導入到 trust store 中然後指派給 java 程序。
㈧ 用java做一個httpClient 發送https 的get請求,需要證書驗證的那種,求大神指點一下!
你那個 SSLSocketFactory(ks) 是自己的類?
你有用過 KeyManager.init (...)? 和 TrustManager.init(...) ?
想要在連接建立過程上互動式的彈出確認對話框來的話需要我們自己提供一個 KeyManager 和 TrustManager 的實現類,這有點復雜,你可以看一個 Sun 的 X509KeyManager 是怎麼做的,默認地情況下它是從自動搜索匹配的 subject ,我們需要用自己提供的方式彈出確認的過程還不是全自動,另外一個賬戶可能有多個數字證書,比如支付寶我們就有多個簽發時間不一樣的數字證書,在連接建立時 IE 會提示我們選擇其中的一個來使用,銀行的 U 盾在安裝多張數字證書時也會提示我們選擇其中一個對應到你正在使用的銀行卡號的那張證書。
㈨ 誰知道如何屏蔽掉htmlunit拋出的各種異常
在main函數裡面加上:
1
2
3
4
5
6
7
LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit")
.setLevel(Level.OFF);
java.util.logging.Logger.getLogger("org.apache.commons.httpclient")
.setLevel(Level.OFF);
追問:
不管用呀,還是往外拋
追答:
是不是這些代碼所在的位置的問題,我測試了一個簡單的只是下載網頁源碼的類,放在最前面不會拋異常,放在HtmlPage page = client.getPage(url);的後面就會拋異常。
可以添加代碼如下: 1 WebClient client = new WebClient(); 2 3 client.setIncorrectnessListener(new SilentIncorrectnessListener()); 4 //js異常控制主要的一步 5 client.getOptions().setJavaScriptEnabled(false); 6 client.setCssErrorHandler(new QuietCssErrorHandler()); 7 client.getOptions().(false); 8 9 client.getOptions().(false);10 //設置日誌級別11 java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);