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

完!

相关推荐
midsummer_woo1 小时前
【2025年】解决Burpsuite抓不到https包的问题
网络协议·http·https
光芒Shine1 小时前
【物联网-TCP/IP】
网络·网络协议·tcp/ip
小白杨树树3 小时前
【WebSocket】SpringBoot项目中使用WebSocket
spring boot·websocket·网络协议
云计算-Security4 小时前
如何理解 IP 数据报中的 TTL?
网络协议·tcp/ip
itachi-uchiha5 小时前
命令行以TLS/SSL显式加密方式访问FTP服务器
服务器·网络协议·ssl
稳联技术5 小时前
实践提炼,EtherNet/IP转PROFINET网关实现乳企数字化工厂增效
网络·网络协议·tcp/ip
Icoolkj6 小时前
WebRTC 与 WebSocket 的关联关系
websocket·网络协议·webrtc
红米饭配南瓜汤6 小时前
WebRTC中的几个Rtp*Sender
网络·网络协议·音视频·webrtc·媒体
moppol7 小时前
SSL/TLS握手全流程拆解:从“Hello“到“安全通道“的每一个字节
网络·安全·ssl
猫头虎8 小时前
[特殊字符]解决 “IDEA 登录失败。不支持早于 14.0 的 GitLab 版本” 问题的几种方法
java·ide·网络协议·http·https·gitlab·intellij-idea