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

完!

相关推荐
esmember4 小时前
电路研究9.2.6——合宙Air780EP中HTTP——HTTP GET 相关命令使用方法研究
网络·网络协议·http·at指令
weisian1517 小时前
消息队列篇--通信协议篇--STOMP(STOMP特点、格式及示例,WebSocket上使用STOMP,消息队列上使用STOMP等)
websocket·网络协议
追风赶月、9 小时前
【网络】传输层协议UDP
网络·网络协议·udp
霸王蟹10 小时前
http和https的区别?
网络·笔记·网络协议·学习·http·https
精通HelloWorld!10 小时前
使用HttpClient和HttpRequest发送HTTP请求
java·spring boot·网络协议·spring·http
泪不是Web妳而流11 小时前
BurpSuite抓包与HTTP基础
网络·经验分享·网络协议·安全·http·网络安全·学习方法
大秦王多鱼11 小时前
Kafka SSL(TLS)安全协议
安全·kafka·ssl
zhuyasen11 小时前
多维度详细比较 kratos、go-zero、goframe、sponge 框架
后端·http·微服务·rpc·golang
ybq1951334543113 小时前
javaEE-6.网络原理-http
网络·网络协议·http
我的青春不太冷14 小时前
《深入理解HTTP交互与数据监控:完整流程与优化实践》
网络·经验分享·科技·网络协议·学习·http·架构