解决“javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.1.110 not verifie”的问题
作为一名经验丰富的开发者,你可以向刚入行的小白解释如何解决“javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.1.110 not verified”问题。以下是一个详细的步骤和相应的代码示例。
流程图
flowchart TD
A[创建 SSLContext 实例] --> B[创建 TrustManager 实例]
B --> C[初始化 KeyStore]
C --> D[创建 SSLContext]
D --> E[创建 SSLSocketFactory]
E --> F[创建 HostnameVerifier]
F --> G[设置 HostnameVerifier]
G --> H[创建 HttpsURLConnection]
H --> I[设置 SSLSocketFactory]
H --> J[设置 HostnameVerifier]
步骤
- 创建 SSLContext 实例:SSLContext 类用于创建 SSL/TLS 安全套接字。你可以使用其中一个 getInstance 方法来获取 SSLContext 实例。
SSLContext sslContext = SSLContext.getInstance("TLS");
- 创建 TrustManager 实例:TrustManager 是一个接口,用于验证远程服务器的证书。X509TrustManager 是 TrustManager 的一个实现类,它可以接受任何证书。
TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不验证客户端证书
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不验证服务器证书
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}};
- 初始化 KeyStore:KeyStore 用于存储证书和私钥。在这个步骤中,我们需要加载一个空的 KeyStore。
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
- 创建 SSLContext:使用 SSLContext 的 init 方法将 TrustManager 初始化,并将其传递给 SSLContext。
sslContext.init(null, trustManagers, new SecureRandom());
- 创建 SSLSocketFactory:SSLSocketFactory 是用于创建 SSL/TLS 安全套接字的工厂类。我们可以使用 SSLContext 的 getSocketFactory 方法来获取 SSLSocketFactory 实例。
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
- 创建 HostnameVerifier:HostnameVerifier 用户验证主机名是否匹配服务器证书中的主机名。
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// 不验证主机名
return true;
}
};
- 设置 HostnameVerifier:在创建 HttpsURLConnection 之前,需要将刚才创建的 HostnameVerifier 设置为默认的 HostnameVerifier。
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
- 创建 HttpsURLConnection:HttpsURLConnection 是用于进行 HTTPS 请求的类。
URL url = new URL("
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
- 设置 SSLSocketFactory:将刚才创建的 SSLSocketFactory 设置为 HttpsURLConnection 的 SSLSocketFactory。
connection.setSSLSocketFactory(sslSocketFactory);
- 设置 HostnameVerifier:将刚才创建的 HostnameVerifier 设置为 HttpsURLConnection 的 HostnameVerifier。
connection.setHostnameVerifier(hostnameVerifier);
代码示例
import javax.net.ssl.*;
import java.io.IOException;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class SSLExample {
public static void main(String[] args) throws Exception {
// 创建 SSLContext 实例
SSLContext sslContext = SSLContext.getInstance("TLS");
// 创建 TrustManager 实例
TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不验证客户端证书
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 不验证服务器证书
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return