【问题标题】:Spring RestTemplate I/O error: No peer certificateSpring RestTemplate I/O 错误:没有对等证书
【发布时间】:2013-08-27 21:50:43
【问题描述】:

我在尝试获取 https 资源时总是遇到同样的错误:

org.springframework.web.client.ResourceAccessException: I/O error: No peer certificate; nested exception is javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

我有一个运行我的应用程序的自签名虚拟主机,该应用程序在 http 上运行良好,但我需要 https

这是我在 android 应用程序中的代码:

mRestTemplate = new RestTemplate();
mRestTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
mRestTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

final ResponseObject responseObject = mRestTemplate.postForObject(APP_URL, requestObject, ResponseObject.class);

更新 1

  • 我尝试了@nilesh 提出的解决方案,但没有奏效。

  • 我尝试this solution 时出现同样的错误

    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue(params, true);
    
    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
    
    client = DefaultHttpClient(conMgr, params);
    
    final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setHttpClient(client);
    
    mRestTemplate = new RestTemplate();
    mRestTemplate.setRequestFactory(factory);
    
  • 我尝试this solution 没有成功,同样的错误

    1. 获取所有必需的证书(根证书和任何中间 CA)
    2. 使用 keytool 和 BouncyCastle 提供程序创建密钥库并导入证书
    3. 在您的 Android 应用程序中加载密钥库并将其用于安全连接 不要使用标准的 java.net.ssl.HttpsURLConnection 进行安全连接。使用 Apache HttpClient(第 4 版 atm)库,它已经内置在 android 中。它建立在 java 连接库之上,在我看来,它更快、更好的模块化且更易于理解。

【问题讨论】:

    标签: android spring ssl resttemplate self-signed


    【解决方案1】:

    在使用 RestTemplate 发出任何 Http 请求之前运行以下方法。这对我有用。

    public void trustSelfSignedSSL() {
            try {
                SSLContext ctx = SSLContext.getInstance("TLS");
                X509TrustManager tm = new X509TrustManager() {
    
                    public void checkClientTrusted(X509Certificate[] xcs,
                            String string) throws CertificateException {
                    }
    
                    public void checkServerTrusted(X509Certificate[] xcs,
                            String string) throws CertificateException {
                    }
    
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
    
                    @Override
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] arg0, String arg1)
                            throws java.security.cert.CertificateException {
                    }
    
                    @Override
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] arg0, String arg1)
                            throws java.security.cert.CertificateException {
    
                    }
                };
                ctx.init(null, new TrustManager[] { tm }, null);
                SSLContext.setDefault(ctx);
            } catch (Exception ex) {
                throw new RuntimeException("Exception occurred ",ex)
            }
        }
    

    【讨论】:

    • 我有一个问题SSLContext.setDefault 仅适用于 api 9+ 我需要 api 8 的解决方案,但这不起作用。
    • 什么是 api 9+?上面的代码适用于 jdk 1.6。导入是-> 导入 javax.net.ssl.SSLContext
    • 我确实在您提到的链接中看到了 SSLContext.setDefault。您的意思是发送其他链接吗?
    • @nilesh - 你是如何将 trustSelfSignedSSL() 方法设置为 rest 模板的?
    猜你喜欢
    • 1970-01-01
    • 2015-08-02
    • 2019-01-21
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 2014-10-15
    相关资源
    最近更新 更多