当前位置:   article > 正文

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

peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
网上基本上都是信任所有证书来解决 SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER

这个方法的代码如下:

  1. public static String httpsPostInvoke(String url,Map<String, Object> map) throws IOException, ServiceException {
  2. HttpClient client = new DefaultHttpClient();
  3. String str = "";
  4. try {
  5. X509TrustManager xtm = new X509TrustManager(){ //创建TrustManager
  6. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
  7. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
  8. public X509Certificate[] getAcceptedIssuers() { return null; }
  9. };
  10. SSLContext ctx = SSLContext.getInstance("TLS");
  11. ctx.init(null, new TrustManager[]{xtm}, null);
  12. SSLSocketFactory socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  13. client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
  14. List<NameValuePair> params = new ArrayList<NameValuePair>();//构建POST请求的参数
  15. for (String key : map.keySet()) {
  16. String value = null;
  17. Object obj = null;
  18. if((obj = map.get(key)) != null){
  19. value = obj.toString();
  20. }
  21. params.add(new BasicNameValuePair(key, value));
  22. }
  23. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
  24. HttpPost post = new HttpPost(url);//创建HttpPost
  25. post.setEntity(entity);
  26. HttpResponse response = client.execute(post);
  27. if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
  28. throw new ServiceException("Http接口状态出错("
  29. + response.getStatusLine().getStatusCode() + ")");
  30. }
  31. str = EntityUtils.toString(response.getEntity());
  32. } catch (NoSuchAlgorithmException e) {
  33. e.printStackTrace();
  34. } catch (KeyManagementException e) {
  35. e.printStackTrace();
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }finally {
  39. client.getConnectionManager().shutdown();
  40. return str;
  41. }
  42. }
执行,ok,没报javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

但是,信任所有的证书,对于强迫症的我和程序猿绝对不能写死的一贯原则,我...又TM花了很长时间,脑补了很多ssl、https的知识,结合网上的代码,发现是可以信任指定证书的,如下代码:

  1. public static String httpsPostInvoke(String url,Map<String, Object> map) throws IOException, ServiceException {
  2. InputStream inputStream = null;
  3. HttpClient httpClient = new DefaultHttpClient();
  4. String result = "";
  5. try{
  6. //从 inputStream 加载 CA 证书
  7. inputStream = NetworkUtil.class.getResourceAsStream("/testCa.cer");
  8. CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
  9. Certificate certificate = certificateFactory.generateCertificate(inputStream);
  10. //构造含有信任 CA 证书的 KeyStore
  11. KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
  12. trustStore.load(null, null);
  13. trustStore.setCertificateEntry("myalias", certificate);
  14. SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
  15. httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
  16. List<NameValuePair> params = new ArrayList<NameValuePair>();//构建POST请求的参数
  17. for (String key : map.keySet()) {
  18. String value = null;
  19. Object obj = null;
  20. if((obj = map.get(key)) != null){
  21. value = obj.toString();
  22. }
  23. params.add(new BasicNameValuePair(key, value));
  24. }
  25. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
  26. HttpPost post = new HttpPost(url);
  27. post.setEntity(entity);
  28. HttpResponse response = httpClient.execute(post);
  29. if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
  30. throw new ServiceException("Http接口状态出错("
  31. + response.getStatusLine().getStatusCode() + ")");
  32. }
  33. result = EntityUtils.toString(response.getEntity());
  34. } catch (CertificateException e) {
  35. e.printStackTrace();
  36. } catch (KeyStoreException e) {
  37. e.printStackTrace();
  38. } catch (NoSuchAlgorithmException e) {
  39. e.printStackTrace();
  40. } catch (KeyManagementException e) {
  41. e.printStackTrace();
  42. } catch (UnrecoverableKeyException e) {
  43. e.printStackTrace();
  44. } finally {
  45. if(null != inputStream){
  46. inputStream.close();
  47. }
  48. httpClient.getConnectionManager().shutdown();
  49. }
  50. return result;
  51. }

执行......还是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!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/692256
推荐阅读
相关标签
  

闽ICP备14008679号