https接口httpRequest.request请求报错:“SSL peer certificate or SSH remote key was not OK”。
请问:
- httpRequest.request怎样进行证书验证。
- httpRequest.request能否忽略证书认证访问https接口。
https接口httpRequest.request请求报错:“SSL peer certificate or SSH remote key was not OK”。
请问:
HttpRequest.request的证书验证通常依赖于底层的HTTP库,如Apache HttpClient或OkHttp。这些库在建立SSL连接时,会使用Java的SSL套接字工厂(SSLSocketFactory)来验证服务器的SSL证书。
如果你想要自定义证书验证,你需要创建一个自定义的SSLSocketFactory,然后将其设置到HttpClient或OkHttp的配置中。在创建自定义SSLSocketFactory时,你可以指定信任的证书和密钥库。
以下是一个使用Apache HttpClient的示例:
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream("my_cert.jks"), "password".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
HttpGet httpGet = new HttpGet("https://example.com");
CloseableHttpResponse response = httpClient.execute(httpGet);
// handle response
} catch (Exception e) {
e.printStackTrace();
}
在这个示例中,我们创建了一个自定义的KeyStore,它包含了我们的证书。然后,我们创建了一个TrustManagerFactory,它使用这个KeyStore来生成TrustManagers。最后,我们创建了一个SSLContext,它使用这些TrustManagers来初始化。
然后,我们使用这个SSLContext创建了一个自定义的SSLConnectionSocketFactory,并设置到了HttpClient中。
注意,NoopHostnameVerifier.INSTANCE是一个不验证主机名的HostnameVerifier,它应该只用于测试环境。在生产环境中,你应该使用默认的HostnameVerifier或自定义的验证主机名的HostnameVerifier。
是的,HttpRequest.request可以配置为忽略SSL证书验证。但是,这通常不推荐在生产环境中使用,因为它会使你的连接容易受到中间人攻击。
如果你确实需要忽略证书验证,你可以创建一个自定义的HostnameVerifier和TrustManager,然后将它们设置到HttpClient或OkHttp的配置中。
以下是一个使用Apache HttpClient的示例:
try {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
URL url = new URL("https://example.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// handle connection
} catch (Exception e) {
e.printStackTrace();
}
在这个示例中,我们创建了一个自定义的TrustManager,它接受所有的证书。然后,我们创建了一个SSLContext,它使用这个TrustManager来初始化。最后,我们将这个SSLContext的SocketFactory设置为了默认的SSLSocketFactory,并将一个接受所有主机名的HostnameVerifier设置为了默认的HostnameVerifier。
但是,请注意,这种方法会使你的连接容易受到中间人攻击,因此只应在测试环境中使用。在生产环境中,你应该使用有效的证书和正确的证书验证。
HTTPS证书是一种数字证书,这种证书的主要作用是保护网站安全性。HTTPS证书校验则是指在建立HTTPS连接时对证书进行校验,保证连接的安全性,使网站的安全性更高。
HTTPS校验主要包括以下几个步骤:
本题中的报错出现在第三步,即客户端对证书校验报错。
客户端对证书的校验验证SSL证书的四个方面:
客户端如果没有对证书进行校验,就会导致中间人攻击,中间人攻击分两种:SSL劫持和SSL剥离。
SSL劫持原理:第三方攻击者会先把自己接到请求方和接收方之间,然后通过自己伪造的证书先模拟成接收方和请求方交换数据,然后再模拟自己为请求方与接收方进行数据交互。一般SSL劫持容易被用于使用者在自己的浏览器等地方安装了未被权威CA认证的证书,因此需要进行证书校验。
SSL剥离通常发生在HTTP请求中,不过现在的网站大部分强制使用HTTPS访问网站,这里不再赘述。
问题1:开发者应对服务端的证书进行上述四个方面的检查,确认无误。若服务端证书是自定义的CA,即SSL证书不是由浏览器中“受信任的根证书颁发机构”颁发,可以通过使用httpRequest.request接口的HttpRequestOptions参数中的caPath设置自定义CA的路径,如果设置了此参数,系统将使用用户指定路径的CA证书,(开发者需保证该路径下CA证书的可访问性),否则将使用系统预设CA证书,系统预设CA证书位置:/etc/ssl/certs/cacert.pem。
问题2:客户端需要对证书进行验证,否则会导致中间人攻击。
参考链接
API参考:HttpRequestOptions