在 Rust 中借助 Tongsuo 实现国密 SSL 证书网站访问
本文包含AI辅助创作内容
Rust 中使用 Tongsuo 访问国密 SSL 证书网站
背景
国密 SSL 证书是基于国家根颁发的支持国密算法的可信服务器证书,符合国密 SSL 安全协议,满足合规要求。它自主可控、安全可靠,支持 SM2/SM3 国密算法,可颁发单域名、多域名、通配符证书,满足政企、国企、事业单位等行业客户实现 HTTPS 加密。目前知名的国密 SSL 证书品牌有 CFCA、TrustAsia 等,可在 爱名网证书超市 购买申请。
传统浏览器对国密 SSL 证书支持并不好,需要使用支持国密的浏览器。同样,常规的接口访问工具也无法直接访问国密证书的接口,需要使用支持国密的工具。
本文以测试网站 https://test1.gmssl.cn 为例,演示如何在 Rust 中通过 Tongsuo 访问国密 SSL 证书网站。
在 Rust 中使用 OpenSSL 访问(失败)
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
use std::io::{Read, Write};
use std::net::TcpStream;
fn main() {
match get_html() {
Ok(html) => {
println!("{}", html);
}
Err(e) => {
print!("{:?}", e);
}
}
}
fn get_html() -> Result<String, Box<dyn std::error::Error>> {
let mut connector_builder = SslConnector::builder(SslMethod::tls())?;
connector_builder.set_verify(SslVerifyMode::NONE);
let connector = connector_builder.build();
let stream = TcpStream::connect("test1.gmssl.cn:443")?;
let mut ssl_stream = connector.connect("test1.gmssl.cn", stream)?;
ssl_stream.write_all(b"GET / HTTP/1.1\r\nHost: test1.gmssl.cn\r\nConnection: close\r\n\r\n")?;
ssl_stream.flush()?;
let mut buffer = [0; 4096];
let size = ssl_stream.read(&mut buffer)?;
let result = String::from_utf8_lossy(&buffer[..size]);
Ok(format!("{}", result))
}
运行前需要配置 OPENSSL_DIR 环境变量,指定 OpenSSL 的目录。在项目的 .cargo/config.toml 中添加:
[env]
OPENSSL_DIR = "D:\\Dev\\Openssl\\OpenSSL-1.1.1-Win64"
编译运行:
Failure(MidHandshakeSslStream { stream: SslStream { stream: TcpStream { addr: 192.168.1.50:55024, peer: 39.99.133.197:443, socket: 468 }, ssl: Ssl { state: "error", verify_result: X509VerifyResult { code: 0, error: "ok" } } }, error: Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 336130315, library: "SSL routines", function: "ssl3_get_record", reason: "wrong version number", file: "ssl\\record\\ssl3_record.c", line: 349 }]))) } })
报错原因:标准 OpenSSL 不支持国密证书。如果需要访问国密 SSL 证书,需要使用支持国密的 OpenSSL 分支,这里推荐使用 Tongsuo。
使用 Tongsuo 支持国密 SSL 证书
Tongsuo 是由阿里巴巴和国家密码管理局合作开发的 OpenSSL 分支,支持 SM2、SM3、SM4、SM9 和 ZUC 算法,以及国密 SSL/TLS 协议。Tongsuo 提供了与 OpenSSL 类似的 API,熟悉 OpenSSL 的开发者可以无缝切换。
1. 引入 Tongsuo 依赖
cargo remove openssl
cargo add tongsuo
cargo clean
2. 编译安装 Tongsuo
从 Tongsuo Releases 下载源码并编译安装,然后将 OPENSSL_DIR 指向 Tongsuo 目录:
[env]
OPENSSL_DIR = "D:\\Dev\\Openssl\\Tongsuo\\Tongsuo-8.4.0"
3. 修改代码
将代码中的 openssl 替换为 tongsuo,核心改动如下:
use tongsuo::ssl::{SslConnector, SslMethod, SslVerifyMode};
let mut connector_builder = SslConnector::builder(SslMethod::ntls_client())?;
connector_builder.enable_ntls();
关键点:目标网站使用 NTLS 协议,需要调用
SslMethod::ntls_client()并启用enable_ntls()。
编译运行后输出:
HTTP/1.1 502 Bad Gateway
Server: gmngx/1.0.3
Date: Fri, 03 Jul 2026 02:42:11 GMT
Content-Type: text/html
Content-Length: 156
Connection: close
Strict-Transport-Security: max-age=31536000
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>gmngx/1.0.3</center>
</body>
</html>
总结
标准 OpenSSL 不支持国密 SSL 证书,访问国密证书网站需要使用 Tongsuo。迁移步骤如下:
- 在
Cargo.toml中将openssl替换为tongsuo - 编译安装 Tongsuo,并将
OPENSSL_DIR指向 Tongsuo 目录 - 代码中将
openssl::替换为tongsuo::,并使用SslMethod::ntls_client()+enable_ntls()启用国密 NTLS 协议
请先 登录后发表评论 ~