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

完!

相关推荐
小贾要学习12 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
Hello_Embed13 小时前
嵌入式上位机开发入门(十九):Socket 状态检测与断线重连
网络·单片机·网络协议·tcp/ip·嵌入式
cheems952713 小时前
[SpringMVC]Cookie 和Session 从无状态协议到状态保存实务
网络·http
添砖java‘’14 小时前
网络层IP
网络·网络协议·tcp/ip·ip
灰子学技术16 小时前
Envoy 底层 TCP 交互、UDS 和事件驱动技术文档
网络·网络协议·tcp/ip
试试勇气17 小时前
C++实现json-rpc框架
网络协议·rpc·json
CDN36017 小时前
高防服务器磁盘 / CPU 爆满?攻击引流与资源扩容实战
运维·服务器·网络协议
听到微笑17 小时前
MCP传输协议演进:从SSE到Streamable HTTP
网络·网络协议·http
哇蛙蛙18 小时前
H3CNE--23.ACL
服务器·网络·经验分享·网络协议·tcp/ip·h3cne
IT枫斗者18 小时前
MSE Nacos Prompt 管理:AI Agent 配置的工程化治理实践
网络·人工智能·websocket·网络协议·prompt·jar