https协议如何通过X509TrustManager接口实现自己创建的证书

本文介绍了如何在遇到非国际认证的自签名HTTPS证书时,通过自定义X509TrustManager接口来实现对其的信任。在浏览器访问这类接口时会提示用户确认,而在代码中模拟服务器请求时,会遇到错误。文中详细讲解了创建信任管理器和配置HTTPS客户端证书的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开通了一个https协议,但是不是国际认证的,自己做的证书,访问一个接口的时候比如 https:/xx.xx.xx.xx/a?c=d的时候,如果在游览器访问,需要用户确认的。如果我要模拟服务器向这个接口发送请求,就会报错误。
我的原代码是:

1 创建信任管理器

 

/**
 * 信任管理器
 * 
 * @author liufeng
 * @date 2013-04-10
 */
public class MyX509TrustManager implements X509TrustManager {

	// 检查客户端证书
	public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	}

	// 检查服务器端证书
	public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	}

	// 返回受信任的X509证书数组
	public X509Certificate[] getAcceptedIssuers() {
		return null;
	}
}

 

2。httpsclient 创建证书

/**
	 * 发送https请求
	 * 
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式(GET、POST)
	 * @param outputStr 提交的数据
package com.example.kucun2.function; import android.content.Context; import android.util.Log; import java.io.InputStream; import java.security.KeyStore; import java.security.MessageDigest; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.Set; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import okhttp3.OkHttpClient; public class TLSUtils { private static final String TAG = "TLSUtils"; private static final String CERT_TYPE = "X.509"; private static final String SSL_PROTOCOL = "TLSv1.2"; /** * 创建安全客户端(支持动态证书名) * @param context 应用上下文 * @param certAssetName assets目录中的证书文件名 * @return 配置好的OkHttpClient */ public static OkHttpClient createSecureClient(Context context, String certAssetName) { try { // 创建自定义信任管理器 X509TrustManager trustManager = createTrustManager(context, certAssetName); // 初始化SSL上下文 SSLContext sslContext = SSLContext.getInstance(SSL_PROTOCOL); sslContext.init(null, new TrustManager[]{trustManager}, null); return new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), trustManager) .hostnameVerifier((hostname, session) -> { // 安全的主机名验证(仅允许特定IP) return "192.168.1.16".equals(hostname); }) .build(); } catch (Exception e) { Log.e(TAG, "创建安全客户端失败", e); throw new RuntimeException("TLS初始化异常", e); } } /** * 创建信任管理器 * @param context 应用上下文 * @param certAssetName 证书文件名 * @return 自定义信任管理器 */ private static X509TrustManager createTrustManager(Context context, String certAssetName) throws Exception { // 使用try-with-resources确保流关闭 try (InputStream certStream = context.getAssets().open(certAssetName)) { CertificateFactory cf = CertificateFactory.getInstance(CERT_TYPE); Certificate cert = cf.generateCertificate(certStream); // 创建包含证书的KeyStore KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); keyStore.setCertificateEntry("changeit", cert); // 初始化TrustManagerFactory TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); tmf.init(keyStore); // 获取并返回X509TrustManager for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { return (X509TrustManager) tm; } } throw new IllegalStateException("未找到X509TrustManager"); } } private static final Set<String> TRUSTED_FINGERPRINTS = new HashSet<String>() {{ add("SHA256: 61:7D:4B:99:4C:96:93:A6:29:84:F8:F2:28:4C:84:2B:16:7C:56:D3:67:40:F0:D5:07:91:DE:F5:B0:E6:3A:F7"); // 替换为实际指纹 }}; public static OkHttpClient createSecureClient(Context context) { try { X509TrustManager trustManager = createFingerprintTrustManager(); SSLContext sslContext = SSLContext.getInstance("TLSv1.3"); sslContext.init(null, new TrustManager[]{trustManager}, null); return new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), trustManager) .hostnameVerifier((hostname, session) -> "192.168.1.16".equals(hostname)) .build(); } catch (Exception e) { Log.e(TAG, "安全客户端创建失败", e); throw new SecurityException("TLS初始化失败", e); } } private static X509TrustManager createFingerprintTrustManager() { return new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { try { for (X509Certificate cert : chain) { String fingerprint = getCertFingerprint(cert, "SHA-256"); if (!TRUSTED_FINGERPRINTS.contains(fingerprint)) { throw new SecurityException("证书指纹不匹配: " + fingerprint); } cert.checkValidity(); } } catch (Exception e) { throw new SecurityException("服务器证书验证失败", e); } } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }; } private static String getCertFingerprint(X509Certificate cert, String algorithm) throws Exception { MessageDigest md = MessageDigest.getInstance(algorithm); return bytesToHex(md.digest(cert.getEncoded())); } private static String bytesToHex(byte[] bytes) { StringBuilder hex = new StringBuilder(); for (byte b : bytes) { hex.append(String.format("%02X", b)); } return hex.toString(); } }
最新发布
06-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值