在 Android 或 Java 项目中使用 OkHttp 请求 HTTPS 接口时,如果目标服务器使用了 自签名证书,默认是无法建立连接的(因为证书不在系统信任链中)。我们需要手动 将自签名证书添加到 OkHttp 的信任列表中。
✅ 场景说明
- 使用 OkHttp 访问 
https://your.server.com - 该服务器使用了 自签名证书(不是 CA 机构签发)
 - 报错如:
javax.net.ssl.SSLHandshakeException: ... 
✅ 解决方案:信任指定证书(推荐)
你需要:
- 拿到 
.cer或.crt证书文件(Base64 编码) - 加载该证书到 
TrustManager - 构造 OkHttp 的 
SSLSocketFactory 
🔐 示例代码(Java 或 Android 使用 OkHttp 3.x/4.x)
public OkHttpClient getUnsafeOkHttpClient(Context context) {
    try {
        // Step 1:从 assets 目录加载证书(cert.crt 为自签名证书)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = context.getAssets().open("cert.crt");  // 放到 assets 目录
        Certificate ca = cf.generateCertificate(caInput);
        caInput.close();
        // Step 2:创建 KeyStore 并加入受信证书
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);
        // Step 3:创建 TrustManagerFactory
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
        // Step 4:创建 SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        // Step 5:构建 OkHttpClient
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0])
                .hostnameVerifier((hostname, session) -> true);  // 可选:关闭主机名验证(开发用)
        return builder.build();
    } catch (Exception e) {
        e.printStackTrace();
        return new OkHttpClient();  // 失败返回默认客户端
    }
}
✅ 证书获取方式
- 浏览器访问服务器,点 HTTPS 小锁 → 查看证书 → 导出为 
.crt - 或使用命令行提取:
 
openssl s_client -connect your.server.com:443 -showcerts
复制其中的 -----BEGIN CERTIFICATE----- 到 -----END CERTIFICATE----- 部分,保存为 cert.crt
✅ cert.crt 放置路径(Android)
- 放到 
assets/文件夹中 - 保证文件名与代码中的一致
 
⚠️ 注意事项
- 不要在生产中使用 
hostnameVerifier((hostname, session) -> true),这会绕过域名校验(有安全风险) - 自签证书方案更适合内网通信、开发调试环境
 
✅ 需要更安全/灵活的方式?
可以用 [OkHttp + 自定义 TrustManager + 多证书信任链] 或 结合 [BouncyCastle] 提高安全性。告诉我你的需求:
- 是否部署在 Android 或 Java 后端?
 - 是否需要支持多个自签名证书?
 - 是否希望与 Retrofit 集成?
 
好的!以下是一个 完整的 OkHttp 客户端,包含了如何在 Android 或 Java 项目中处理 自签名证书,并确保所有的 HTTPS 请求都能信任你的自签名证书。
📁 项目结构
- assets/cert.crt — 你的自签名证书文件,放在 Android 项目的 
assets文件夹里。 - 通过 OkHttp 通过 
TrustManager实现自签名证书的信任。 
🔐 完整代码:自签名证书信任设置
Step 1: 创建 UnsafeOkHttpClient.java
import android.content.Context;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class UnsafeOkHttpClient {
    public static OkHttpClient getUnsafeOkHttpClient(Context context) {
        try {
            // 1. 从 assets 加载自签名证书文件
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = context.getAssets().open("cert.crt");  // 放置证书文件在 assets 目录
            Certificate ca = cf.generateCertificate(caInput);
            caInput.close();
            // 2. 将证书加入到 KeyStore
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
            // 3. 创建 TrustManagerFactory 并初始化
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
            // 4. 使用 SSLContext 设置自签名证书
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            // 5. 创建 OkHttpClient,配置 SSL 和自定义的 TrustManager
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0])
                    .hostnameVerifier((hostname, session) -> true);  // 默认信任所有主机名,适合开发环境
            return builder.build();
        } catch (Exception e) {
            e.printStackTrace();
            return new OkHttpClient();  // 如果失败,则返回默认 OkHttpClient
        }
    }
    // 使用 OkHttpClient 发起 HTTPS 请求示例
    public static void makeRequest(Context context) {
        OkHttpClient client = getUnsafeOkHttpClient(context);
        Request request = new Request.Builder()
                .url("https://your.server.com")  // 你的服务器地址
                .build();
        client.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(okhttp3.Call call, java.io.IOException e) {
                e.printStackTrace();
            }
            @Override
            public void onResponse(okhttp3.Call call, Response response) throws java.io.IOException {
                if (response.isSuccessful()) {
                    System.out.println("Response: " + response.body().string());
                } else {
                    System.out.println("Request failed!");
                }
            }
        });
    }
}
Step 2: 在 MainActivity.java 中调用
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 调用自定义 OkHttp 客户端进行 HTTPS 请求
        UnsafeOkHttpClient.makeRequest(this);
    }
}
📂 资源文件
1. assets/cert.crt — 你的自签名证书文件(Base64 编码的 .crt)
将自签名证书文件 cert.crt 放到 assets 目录下。
获取证书的方式:
- 浏览器:右键点击 HTTPS 页面,查看证书并导出为 
.crt文件。 - 命令行:运行 
openssl命令来提取证书: 
openssl s_client -connect your.server.com:443 -showcerts
复制证书内容并保存为 .crt 文件。
🛠️ 运行示例:
- 将 
cert.crt放入 Android 项目的assets文件夹。 - 在 
MainActivity中调用UnsafeOkHttpClient.makeRequest()方法发起请求。 - 在 Android 模拟器或真机上运行该应用,OkHttp 会通过自签名证书与服务器建立 HTTPS 连接。
 
⚠️ 注意事项:
- 生产环境不建议绕过主机名验证:在生产环境中,不应该绕过 
hostnameVerifier,你需要确保服务器的域名正确。 - 适用于 开发、内网环境 或 自签证书 测试。
 
发表回复