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");
}

完!

相关推荐
hbz-39 分钟前
【HBZ分享】如何规避TCP的洪水攻击
网络·网络协议·tcp/ip
Comedy_宁40 分钟前
TCP/IP协议超时重传,以及应用层超时重传一文详解
网络·网络协议·tcp/ip
fredricen7 小时前
CentOS7.9下yum升级Apache HTTP Server2.4.6到2.4.60
网络协议·http·apache
会讲英语的码农8 小时前
【计算机网络】第一章 概要
运维·服务器·网络协议
w_t_y_y8 小时前
Websocket
网络·websocket·网络协议
kinlon.liu12 小时前
Web应用安全实用建议
前端·网络·网络协议·安全·centos
gavinwang15215212 小时前
一文解决:你与该网站的连接不是私密连接,存在安全隐患
安全·web安全·网络安全·https·ssl
yaoxin52112313 小时前
第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪
网络·网络协议·http
中云DDoS CC防护蔡蔡15 小时前
爬虫爬数据犯法吗
运维·服务器·爬虫·python·http
xw-pp15 小时前
从输入 URL 到页面展示到底发生了什么?
网络协议·tcp/ip·http·网络安全·https·tcpdump