7.1 KiB
7.1 KiB
Java 客户端使用手册
1. 概述
Java 国密 SSL 客户端提供两种使用方式:
- 标准 TLS 客户端(基于 BouncyCastle):支持标准 ECDSA/RSA 证书的 SSL 连接
- JNI 国密客户端(基于 Tongsuo 原生库):支持国密 SM2/SM3/SM4 密码套件的 SSL 连接
2. 快速开始
2.1 启动测试服务端
export LD_LIBRARY_PATH=/opt/tongsuo-8.4.0/lib64:$LD_LIBRARY_PATH
CERT_DIR=/mnt/d/workbench/gateway2/java-client/certs
TONGSUO=/opt/tongsuo-8.4.0/bin/openssl
# 单向认证
$TONGSUO s_server -accept 7443 \
-cert $CERT_DIR/server-ecdsa-cert.pem \
-key $CERT_DIR/server-ecdsa-key.pem \
-WWW -quiet &
# 双向认证
$TONGSUO s_server -accept 7444 \
-cert $CERT_DIR/server-ecdsa-cert.pem \
-key $CERT_DIR/server-ecdsa-key.pem \
-CAfile $CERT_DIR/ca-ecdsa-cert.pem \
-verify 1 \
-WWW -quiet &
2.2 运行客户端
cd /mnt/d/workbench/gateway2/java-client
export LD_LIBRARY_PATH=/opt/tongsuo-8.4.0/lib64:$LD_LIBRARY_PATH
# JNI 国密单向认证
java -Djava.library.path=native \
-jar target/ssl-client-1.0-SNAPSHOT.jar \
jni-oneway 127.0.0.1 7443 /
# JNI 国密双向认证
java -Djava.library.path=native \
-jar target/ssl-client-1.0-SNAPSHOT.jar \
jni-twoway 127.0.0.1 7444 \
/path/to/client-cert.pem \
/path/to/client-key.pem \
/path/to/ca.pem \
/
3. 命令行参考
3.1 命令格式
java -Djava.library.path=native -jar ssl-client.jar <mode> [args...]
3.2 模式列表
| 模式 | 说明 | 认证方式 |
|---|---|---|
https-oneway |
HTTPS 单向认证 | 标准 TLS |
https-twoway |
HTTPS 双向认证 | 标准 TLS + 客户端证书 |
tcp-oneway |
TCP+SSL 单向认证 | 标准 TLS |
tcp-twoway |
TCP+SSL 双向认证 | 标准 TLS + 客户端证书 |
https-proxy |
HTTPS 代理模式 | SSL 隧道直连 |
jni-oneway |
JNI 国密单向认证 | 国密 SM4-GCM-SM3 |
jni-twoway |
JNI 国密双向认证 | 国密 + 客户端证书 |
3.3 参数说明
https-oneway / tcp-oneway
java -jar ssl-client.jar https-oneway <host> <port> [path]
java -jar ssl-client.jar tcp-oneway <host> <port> [message]
https-twoway / tcp-twoway
java -jar ssl-client.jar https-twoway <host> <port> <keystore> <password> [path]
java -jar ssl-client.jar tcp-twoway <host> <port> <keystore> <password> [message]
jni-oneway
java -Djava.library.path=native \
-jar ssl-client.jar jni-oneway <host> <port> [path]
协商密码套件: TLS_SM4_GCM_SM3 / TLS_SM4_CCM_SM3
jni-twoway
java -Djava.library.path=native \
-jar ssl-client.jar jni-twoway <host> <port> \
<client-cert.pem> <client-key.pem> <ca.pem> [path]
https-proxy
java -jar ssl-client.jar https-proxy <targetHost> <targetPort> [path]
4. 编程接口
4.1 GmSSLClient(JNI 国密客户端)
import com.gateway.ssl.jni.GmSSLClient;
// 单向认证
try (GmSSLClient client = new GmSSLClient(
"127.0.0.1", 7443,
null, null, null, null, null)) {
String resp = client.httpGet("/");
}
// 双向认证
try (GmSSLClient client = new GmSSLClient(
"127.0.0.1", 7444,
"/path/to/ca.pem",
"/path/to/client-cert.pem",
"/path/to/client-key.pem",
null, null)) {
String resp = client.httpGet("/");
}
// 自定义数据收发
try (GmSSLClient client = new GmSSLClient(host, port, null, null, null, null, null)) {
client.send("Hello".getBytes("UTF-8"));
byte[] response = client.recv(4096);
}
4.2 HttpsClient(标准 TLS)
SslConfig config = new SslConfig()
.setHost("127.0.0.1").setPort(7443).setTlsProtocol("TLSv1.3");
HttpsClient client = new HttpsClient(config);
String response = client.doGet("/");
4.3 TcpSslClient(标准 TLS)
SslConfig config = new SslConfig()
.setHost("127.0.0.1").setPort(7443).setTlsProtocol("TLSv1.3");
TcpSslClient client = new TcpSslClient(config);
String response = client.sendAndReceive("GET / HTTP/1.0\r\n\r\n");
5. 测试场景
5.1 HTTPS 单向认证
java -jar target/ssl-client-1.0-SNAPSHOT.jar https-oneway 127.0.0.1 7443 /
预期输出:
[HTTPS] Negotiated cipher suite: TLS_AES_256_GCM_SHA384
[HTTPS] Protocol: TLSv1.3
Response: HTTP/1.0 200 ok
5.2 HTTPS 双向认证
java -jar target/ssl-client-1.0-SNAPSHOT.jar \
https-twoway 127.0.0.1 7444 \
certs/client-ecdsa.p12 changeit /
5.3 JNI 国密单向认证
export LD_LIBRARY_PATH=/opt/tongsuo-8.4.0/lib64:$LD_LIBRARY_PATH
java -Djava.library.path=native \
-jar target/ssl-client-1.0-SNAPSHOT.jar \
jni-oneway 127.0.0.1 7443 /
预期输出:
[GMSSL] Cipher: TLS_SM4_GCM_SM3
[GMSSL] Protocol: TLSv1.3
Response: HTTP/1.0 200 ok
5.4 JNI 国密双向认证
export LD_LIBRARY_PATH=/opt/tongsuo-8.4.0/lib64:$LD_LIBRARY_PATH
java -Djava.library.path=native \
-jar target/ssl-client-1.0-SNAPSHOT.jar \
jni-twoway 127.0.0.1 7444 \
certs/client-ecdsa-cert.pem \
certs/client-ecdsa-key.pem \
certs/ca-ecdsa-cert.pem \
/
5.5 TCP+SSL 模式
# 单向
java -jar target/ssl-client-1.0-SNAPSHOT.jar \
tcp-oneway 127.0.0.1 7443 \
"GET / HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
# 双向
java -jar target/ssl-client-1.0-SNAPSHOT.jar \
tcp-twoway 127.0.0.1 7444 \
certs/client-ecdsa.p12 changeit \
"GET / HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
5.6 HTTPS 代理模式
java -jar target/ssl-client-1.0-SNAPSHOT.jar \
https-proxy 127.0.0.1 7443 /
6. 常见问题
6.1 找不到 libgmssl_jni.so
Exception: no gmssl_jni in java.library.path
解决: 确保 -Djava.library.path=native 指向包含 libgmssl_jni.so 的目录。
6.2 Tongsuo 库版本冲突
/opt/tongsuo-8.4.0/bin/openssl: version OPENSSL_3.0.3 not found
解决: 设置 LD_LIBRARY_PATH=/opt/tongsuo-8.4.0/lib64:$LD_LIBRARY_PATH
6.3 国密套件不可用
Java 标准库不支持国密 SM 密码套件。使用 jni-oneway / jni-twoway 模式通过 JNI 调用 Tongsuo 原生库。
6.4 PKCS12 加载失败
Caused by: Unknown named curve: 1.2.156.10197.1.301
原因: SM2 曲线 OID 不被 Java 识别。使用 ECDSA (prime256v1) 证书生成 PKCS12,或使用 JNI PEM 方式加载。
7. 架构说明
+---------------------------------------------+
| Java 应用层 |
| Main.java / GmSSLClient.java |
+---------------------------------------------+
| JNI 桥接层 |
| GmSSLJNI.java -> libgmssl_jni.so |
+---------------------------------------------+
| Tongsuo 原生库 (C) |
| libssl.so / libcrypto.so |
| +-- TLS_SM4_GCM_SM3 |
| +-- TLS_SM4_CCM_SM3 |
| +-- SM2 签名/加密 |
| +-- SM3 摘要 |
| +-- SM4 对称加密 |
+---------------------------------------------+
| TCP 传输层 |
| C 层直接创建 socket, SSL_set_fd 绑定 |
+---------------------------------------------+