1. 程式人生 > >peer not authenticated和Could not generate DH keypair解決方法

peer not authenticated和Could not generate DH keypair解決方法

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
網上基本上都是信任所有證書來解決 SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER

這個方法的程式碼如下:

public static String httpsPostInvoke(String url,Map<String, Object> map) throws IOException, ServiceException {
		
    	HttpClient client = new DefaultHttpClient();
    	String str = "";
    	
        try { 
        	X509TrustManager xtm = new X509TrustManager(){   //建立TrustManager 
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} 
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} 
                public X509Certificate[] getAcceptedIssuers() { return null; }
            };
            SSLContext ctx = SSLContext.getInstance("TLS"); 
            ctx.init(null, new TrustManager[]{xtm}, null); 
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory)); 

            List<NameValuePair> params = new ArrayList<NameValuePair>();//構建POST請求的引數
    		for (String key : map.keySet()) {
    			String value = null;
    			Object obj = null;
    			if((obj = map.get(key)) != null){
    				value = obj.toString();
    			}
    			params.add(new BasicNameValuePair(key, value));
    		}
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
    		HttpPost post = new HttpPost(url);//建立HttpPost 
    		post.setEntity(entity);
            
             
    		HttpResponse response = client.execute(post);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				throw new ServiceException("Http介面狀態出錯("
						+ response.getStatusLine().getStatusCode() + ")");
			}
			str = EntityUtils.toString(response.getEntity());
        } catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}finally { 
        	client.getConnectionManager().shutdown(); 
        	return str;
        } 
    } 
執行,ok,沒報javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

但是,信任所有的證書,對於強迫症的我和程式猿絕對不能寫死的一貫原則,我...又TM花了很長時間,腦補了很多ssl、https的知識,結合網上的程式碼,發現是可以信任指定證書的,如下程式碼:

public static String httpsPostInvoke(String url,Map<String, Object> map) throws IOException, ServiceException {
    	
    	InputStream inputStream = null;
    	HttpClient httpClient = new DefaultHttpClient();
    	String result = "";
    	
    	try{
    		//從 inputStream 載入 CA 證書
    		inputStream = NetworkUtil.class.getResourceAsStream("/testCa.cer");
    		CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    		Certificate certificate = certificateFactory.generateCertificate(inputStream);
    		
    		//構造含有信任 CA 證書的 KeyStore
        	KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        	trustStore.load(null, null);
        	trustStore.setCertificateEntry("myalias", certificate);
        	
        	SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
            httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
        	
            List<NameValuePair> params = new ArrayList<NameValuePair>();//構建POST請求的引數
    		for (String key : map.keySet()) {
    			String value = null;
    			Object obj = null;
    			if((obj = map.get(key)) != null){
    				value = obj.toString();
    			}
    			params.add(new BasicNameValuePair(key, value));
    		}
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
    		HttpPost post = new HttpPost(url);
    		post.setEntity(entity);
    		
    		HttpResponse response = httpClient.execute(post);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				throw new ServiceException("Http介面狀態出錯("
						+ response.getStatusLine().getStatusCode() + ")");
			}
			result = EntityUtils.toString(response.getEntity());
    	} catch (CertificateException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		} finally {
    		
    		if(null != inputStream){
    			inputStream.close();
    		}
    		
    		httpClient.getConnectionManager().shutdown(); 
    	}
    	
    	return result;
    	
    }
執行......還是javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
想死的心都有了,繼續度娘...沒有啥進展...又過了一段時間,在stackoverflow(英語渣渣的我遇到問題,頓時感覺自己英語可以達到了8級!!)找到如下說明和命令

要把證書匯入到jdk的KeyStore中,如下命令(相信聰明的你看路徑和檔名知道怎麼修改相應的引數了吧):

keytool -importcert -alias myalias -file "C:\Users\zhangxiaoning\Desktop\testCa.cer" -keystore "D:\Java\jdk1.6.0_45\jre\lib\security\cacerts" -storepass changeit
另外,騷年們想看命令的說明可以參考一下blog,傳送門:
http://www.cnblogs.com/benio/archive/2010/09/15/1826990.html

繼續執行程式碼...javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated,我已掛了......
繼續百度、實驗、驗證,排除一系列可能性,發現...好像匯出的證書有問題...
我居然把介面的URL在瀏覽器輸入錯了,原先匯出的證書不是介面url的證書,是兩個不同的url!不同的域名!該死的供應商,給了我錯誤的URL,我也沒注意,怪我!
好吧重新匯出證書.順便記錄chrome怎麼匯出。如圖:



其他預設就行了。

執行程式...
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated


我也不知道怎麼表述我的心情了。
找資料,看到了一個blog說好像是jdk版本問題,把jdk1.6.0_45\jre\lib\security下的兩個jar包換成jdk1.6以上的jar包,換了後執行直接報了classnotfound
算了,先用jdk1.7的執行,呼叫成功 = =
但是公司的很多系統都是用jdk1.6的,用jdk1.7的話,可能會有問題,所以繼續找資料。

在無意中,百度到了一句,java ssl網路的debug log列印,在你要呼叫介面前加入以下一句:

System.setProperty("javax.net.debug", "ssl,handshake");

呼叫https介面前會列印一系列log,前面一堆的可以忽略,直接看最下面的,比如我的:


知道了問題,搜尋的範圍變小了很多了,直接百度:javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

查看了很多資料,終於找到了原因,jdk1.6只支援1024位元組的DH,我發現我證書的公鑰是2048位元組的,所以報錯了,jdk1.7以上支援,所以成功。


可以檢視詳細的說明:

傳送門:https://stackoverflow.com/questions/6851461/java-why-does-ssl-handshake-give-could-not-generate-dh-keypair-exception

https://github.com/syncany/syncany/issues/483

所以解決方法是:

1.下載jar包:傳送門:http://download.csdn.net/detail/nk_tf/9609842   (先前在csdn上下載了一份,發現是壞的jar包,我的1分沒了,氣死我了~~)

2.複製這兩個jar包到: $JAVA_HOME/jre/lib/ext 

3.編輯$JAVA_HOME/jre/lib/security/java.security,在9下面加入這句:

security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.8=sun.security.smartcardio.SunPCSC
security.provider.9=sun.security.mscapi.SunMSCAPI
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
重新呼叫,沒報錯,OK!!

相關推薦

peer not authenticatedCould not generate DH keypair解決方法

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 網上基本上都是信任所有證書來解決 SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER這個方法的程式碼如下:

Could not generate DH keypair 解決方案

之前專案中使用HttpClient訪問別人的介面,出現:網上大概說是Java 7 以及早期版本是隻支援 1024 位的 DH Parma的。查閱文件發現JDK7的131版本就已經fix了,在本地講JDK更換到高階的版本後就沒有再出現上述的問題了,該方法可行。不過更換JDK版本

Caused by: java.lang.RuntimeException: Could not generate DH keypair異常處理

一、換新版本JDK7。 二、下載下面兩個jar,並放在你的jdk路徑ext下(我的是C:\Program Files\Java\jdk1.6.0_45\jre\lib\ext),並修改C:\Program Files\Java\jdk1.6.0_45\jre\lib\sec

myeclipse的svn: E175002: java.lang.RuntimeException: Could not generate DH keypair

轉載至:http://blog.csdn.net/yulong_1988/article/details/51459936 自己整理備忘。 報錯問題如下  svn: E175002: OPTIONS request failed on '/svn/word'     s

Unable to resolve dependency forCould not resolve project 的解決辦法,針對AndroidStudio高版本

前提是這樣的:我找了一個AndroidStudio3.0之前版本的專案,把它其中的Module匯入到一個新專案中作為依賴 然後就出現此報錯資訊,老是說Could not resolve project:xxx 解決了一下午。有人說在Setting-Build,Gradle,xxx選項中

unable to load script from assets could not connect to development server解決方案

小編碰到該問題是在利用Android studio正確執行react native專案時遇見,可以正確編譯,但是不能顯示出正確介面,如下圖所示。解決方案:1.設定IP和埠報錯頁面晃動手機,顯示選單——點

git提示錯誤關於錯誤:ssh: Could not resolve hostname github.com: Name or service not known.fatal: Could not read from remote repository.

eight 無法讀取 主機名 github上 錯誤2 winsock nal file drive 關於 Git 使用中出現的錯誤 饑人谷_楠柒 關註 2016.11.02 15:33* 字數 746 閱讀 3607評論 5喜歡 10贊賞 1 關

bitbucket工程改名導致 repository does not exist. fatal: Could not read from remote repository.

在bitbucket上把工程改名了,就忘了。 結果同步時報錯。 先在本地檢視一下 git remote -v 果然是工程的老名字 origin [email protected]:XXX/oldname.git (fetch)origin [email protected]

格式化namenode時:Error: JAVA_HOME is not set and could not be found.

1.格式化namenode 命令:hdfs namenode -format         如果Error: JAVA_HOME is not set and could not be found. &nb

Hadoop初次啟動時 程序啟動失敗 提示JAVA_HOME is not set and could not be found

初次配置好Hadoop偽分散式式之後,啟動./sbin/start-all.sh  命令發現程序啟動失敗, 如下圖所示 jps 命令檢視程序 發現namenode  datanode 均沒有啟動  提示 JAVA_HOME is not set and could no

Could not open ServletContext resource [/WEB-INF/applicationContext.xml]解決方法

拋錯: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-I

localhost: Error: JAVA_HOME is not set and could not be found.

今天開啟 NameNode 和 DataNode 守護程序時出錯localhost: Error: JAVA_HOME is not set and could not be found.1但是JAVA環境變數已經配好了,終端輸入java -version也會顯示版本資訊解決

Could not get lock /var/lib/dpkg/lock的解決方法

E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to lock the administration directory (/var/lib/dpkg/), is

hadoop2 JAVA_HOME is not set and could not be found

啟動yarn的報錯JAVA_HOME not set的處理辦法 問題: JAVA_HOME is not set 解決辦法: 新增兩處: 1.$HADOOP_HOME/etc/hadoop/yarn-env.sh  中新增: -----------------------

Hadoop 2.7 偽分散式安裝配置 Error: JAVA_HOME is not set and could not be found.

問題: 如果你明明安裝配置了 JAVA_HOME 卻還是報錯 如果遇到 Error: JAVA_HOME is not set and could not be found. 的錯誤,而你明

hadoop 啟動 JAVA_HOME is not set and could not be found

[[email protected] hadoop-2.7.2]# sbin/start-dfs.sh 16/07/01 18:38:03 DEBUG util.Shell: setsid exited with exit code 0 16/07/01 18:38

Hdoop 啟動:localhost: Error: JAVA_HOME is not set and could not be found.

其中有 Prepare to Start the Hadoop Cluster Unpack the downloaded Hadoop distribution. In the

CentOS hadoop啟動錯誤 JAVA_HOME is not set and could not be found

... Starting namenodes on [] localhost: Error: JAVA_HOME is not set and could not be found.localhost: Error: JAVA_HOME is not set and cou

Eclipse 開啟提示could not open jvm.cfg檔案的錯誤的解決方法。最近安裝java的過程中遇到這個問題。

一.首先開啟提示的目錄位置,查詢是否存在這個檔案和資料夾。如果不存在的話,表示java安裝過程中出錯,相應的檔案沒有安裝。需要在控制面板中解除安裝java再重新安裝。我遇到的就是這種情況。解除安裝後,重新安裝之前訪問登錄檔,刪除如下資訊在點選開始--》執行-》輸入regedi

macOS 10.12.1 Idea除錯Go程式遇到could not launch process: could not get thread count

我的Idea版本是2016.3,在macOS 10.12.1除錯Go程式會發現報錯: could not launch process: could not get thread count 解決方案