1

我正在尝试将 Https Post 请求发送到使用自签名证书的服务器,并且我收到一个带有错误的异常:peer not authenticated.

我用谷歌搜索,发现问题的原因是服务器使用的是自签名证书。我怎样才能抑制这个错误?

我正在使用以下函数发送发布请求:

public String sendPost(final String request, final String postData) throws ClientProtocolException, IOException  {
    String result = null;
    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(request);
    ByteArrayEntity postDataEntity = new ByteArrayEntity(postData.getBytes());
    httpPost.setEntity(postDataEntity);
    CloseableHttpResponse response = httpclient.execute(httpPost);
    try {
        HttpEntity entity = response.getEntity();
        result = EntityUtils.toString(entity);
        EntityUtils.consume(entity);
    } finally {
        response.close();
    }
    return result;

}

我错过了什么来抑制这个错误?我不想尝试捕捉这个异常。我想正确配置它,以便接受自签名证书。我正在使用 Httpclient 4.1。

谢谢你!

4

2 回答 2

2

您会在网络上找到这个问题的许多答案(包括 ufk 的答案),但它们根本不安全,因为它们完全忽略了自签名服务器证书。

这消除了 SSL 连接的大部分好处,并使您面临中间人攻击。

您可能想要做的是信任特定的自签名服务器证书,而不是盲目地接受任何服务器证书。

关键是在创建 SSL 上下文时将服务器证书链的副本放入信任库。

执行此操作的代码有点太长,无法在此处发布,但碰巧的是,我目前正在撰写一篇关于在 Android 上执行此操作的博客文章。博客文章尚未发布,但示例代码可在GitHub上找到。

于 2013-01-30T18:38:27.990 回答
0
public String sendPost(final String request, final String postData) throws ClientProtocolException, IOException, NoSuchAlgorithmException, KeyManagementException  {
    String result = null;
    SSLContext sslContext = SSLContext.getInstance("SSL");

    // set up a TrustManager that trusts everything
    sslContext.init(null, new TrustManager[] { new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                        System.out.println("getAcceptedIssuers =============");
                        return null;
                }

                public void checkClientTrusted(X509Certificate[] certs,
                                String authType) {
                        System.out.println("checkClientTrusted =============");
                }

                public void checkServerTrusted(X509Certificate[] certs,
                                String authType) {
                        System.out.println("checkServerTrusted =============");
                }
    } }, new SecureRandom());

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(new SSLSocketFactory(sslContext)).build();
    HttpPost httpPost = new HttpPost(request);
    ByteArrayEntity postDataEntity = new ByteArrayEntity(postData.getBytes());
    httpPost.setEntity(postDataEntity);
    CloseableHttpResponse response = httpclient.execute(httpPost);
    try {
        HttpEntity entity = response.getEntity();
        result = EntityUtils.toString(entity);
        EntityUtils.consume(entity);
    } finally {
        response.close();
    }
    return result;

}
于 2013-01-30T17:52:49.140 回答