# Java 客户端使用手册 ## 1. 概述 Java 国密 SSL 客户端提供两种使用方式: 1. **标准 TLS 客户端**(基于 BouncyCastle):支持标准 ECDSA/RSA 证书的 SSL 连接 2. **JNI 国密客户端**(基于 Tongsuo 原生库):支持国密 SM2/SM3/SM4 密码套件的 SSL 连接 ## 2. 快速开始 ### 2.1 启动测试服务端 ```bash 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 运行客户端 ```bash 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 命令格式 ```bash java -Djava.library.path=native -jar ssl-client.jar [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 [path] java -jar ssl-client.jar tcp-oneway [message] ``` #### https-twoway / tcp-twoway ``` java -jar ssl-client.jar https-twoway [path] java -jar ssl-client.jar tcp-twoway [message] ``` #### jni-oneway ``` java -Djava.library.path=native \ -jar ssl-client.jar jni-oneway [path] ``` 协商密码套件: TLS_SM4_GCM_SM3 / TLS_SM4_CCM_SM3 #### jni-twoway ``` java -Djava.library.path=native \ -jar ssl-client.jar jni-twoway \ [path] ``` #### https-proxy ``` java -jar ssl-client.jar https-proxy [path] ``` ## 4. 编程接口 ### 4.1 GmSSLClient(JNI 国密客户端) ```java 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) ```java 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) ```java 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 单向认证 ```bash 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 双向认证 ```bash java -jar target/ssl-client-1.0-SNAPSHOT.jar \ https-twoway 127.0.0.1 7444 \ certs/client-ecdsa.p12 changeit / ``` ### 5.3 JNI 国密单向认证 ```bash 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 国密双向认证 ```bash 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 模式 ```bash # 单向 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 代理模式 ```bash 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 绑定 | +---------------------------------------------+ ```