SSL 之 http只用crt格式证书完成SSL单向认证通信

背景

远程调用第三方服务时,之前都是双向认证,服务器提供jks格式的keystore证书,客户端配置好即可。

今天遇到个奇葩需求,服务器只给根公钥证书(root.crt),还是第三方合法证书,要求单向认证,客户端校验SSL握手时服务器发送的证书,只给了crt公钥。。。。真的服了。没办法,只能自己冲浪解决了,下面是针对我的这种情况,代码实践。测试没啥问题。以供搜到的你参考。

代码

java 复制代码
//这个类实现证书校验
import javax.net.ssl.X509TrustManager;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class CustomTrustManager implements X509TrustManager {
    private static final Logger log = LoggerFactory.getLogger(CustomTrustManager.class);
    private final X509Certificate rootCert;

    public CustomTrustManager(X509Certificate rootCert) {
        this.rootCert = rootCert;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // 根据需求实现检查逻辑
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        boolean found = false;
        final PublicKey publicKey = rootCert.getPublicKey();
        for (X509Certificate cert : chain) {
            try {
                cert.verify(publicKey);
                found = true;
                break;
            } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException |
                     NoSuchProviderException e) {
                log.error("Failed to verify client certificate", e);
            }
        }
        if (!found) {
            throw new CertificateException("No trusted certificate found in the server's certificate chain.");
        }
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }
}

测试代码

java 复制代码
@Test
void testCerts() throws NoSuchAlgorithmException, KeyManagementException, IOException {
    //Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    X509Certificate certificate;
    //加载根证书
    try (InputStream inputStream = new FileInputStream("D:\\certs\\root-new.crt")) {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
    } catch (IOException | java.security.cert.CertificateException e) {
        throw new RuntimeException(e);
    }
    
    X509Certificate rootCert = certificate;

    // 创建SSL上下文并设置为信任所有证书
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, new TrustManager[]{new CustomTrustManager(rootCert)}, null);

    // 获取HttpsURLConnection实例
    HttpsURLConnection connection = (HttpsURLConnection) new URL("https://你的URI").openConnection();
    connection.setSSLSocketFactory(sslContext.getSocketFactory());
    connection.connect();
    System.out.println("2222222222");
    connection.disconnect();
    System.out.println("11111111111");
}

完!

相关推荐
wang090731 分钟前
网络协议之为什么要分层
网络·网络协议
w23617346012 小时前
HTTP vs HTTPS:传输协议的安全演进与核心差异
安全·http·https
穿条秋裤到处跑2 小时前
前端连接websocket服务报错 Unexpected response code: 301
websocket·网络协议·nginx
Suckerbin3 小时前
第十四章-PHP与HTTP协议
开发语言·http·php
千码君20163 小时前
什么是数据链路层的CRC检测以及为什么要放到帧尾?
服务器·网络·网络协议·以太网·奇偶校验·crc检测·以太网帧
后院那片海3 小时前
Web基础与HTTP协议
网络·网络协议·http
问道飞鱼4 小时前
【知识科普】HTTPS 加密中信息的可见性详解
网络协议·http·https·ssl·tls
开***能8 小时前
高炉项目中DeviceNET到Ethernet的转换奥秘
网络·网络协议·自动化
努力也学不会java8 小时前
【网络原理】 网络编程套接字
java·开发语言·网络·网络协议·tcp/ip·php
你不是我我10 小时前
【Java开发日记】OpenFeign 的 9 个坑
java·http·spring cloud