引言
Microsoft Thrifty 是 Apache Thrift 协议的一个高效实现,它为构建高性能 RPC 服务提供了简洁的 API。然而,与一些其他 Thrift 实现不同,Thrifty 本身并没有直接提供 SSL/TLS 加密支持。本文将介绍如何在 Thrifty 客户端中添加 SSL/TLS 支持,以确保客户端与服务器之间的通信安全。
背景
在很多生产环境中,安全通信是必不可少的。SSL/TLS 协议能够提供数据加密、身份验证和数据完整性保护,确保敏感信息在传输过程中不被窃取或篡改。虽然 Thrifty 没有内置 SSL 支持,但我们可以通过扩展其传输层来实现这一功能。
实现原理
通过分析 xthrift 项目(一个对 Thrifty 进行扩展的项目),我们可以看到实现 SSL 支持的关键在于:
- 创建一个自定义的 SSL 上下文工厂
- 扩展 ClientFactory 以支持 SSL 配置
- 使用 Java 内置的 SSL 功能创建安全套接字连接
核心组件
1. SSLContextFactory
SSLContextFactory 是一个用于创建 SSL 上下文的工厂类。它可以从 PEM 格式的证书文件创建 SSLContext:
public class SSLContextFactory {
public static SSLContext createSSLContextFromPEM(File caFile, TrustManagerFactory trustManagerFactory,
long sessionCacheSize, long sessionTimeout) throws IOException {
String content = Files.toString(checkNotNull(caFile,"caFile is null"), StandardCharsets.US_ASCII);
return createSSLContextFromPEM(content, caFile.getAbsolutePath(), trustManagerFactory, sessionCacheSize, sessionTimeout);
}
public static SSLContext createSSLContextFromPEM(String content, String source, TrustManagerFactory trustManagerFactory,
long sessionCacheSize, long sessionTimeout) throws SSLException {
// 实现细节...
}
}
2. PemReader
PemReader 负责读取 PEM 格式的证书文件并将其转换为 DER 格式:
public final class PemReader {
private static final Pattern CERT_PATTERN = Pattern.compile(
"-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)+" + // Header
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
"-+END\\s+.*CERTIFICATE[^-]*-+", // Footer
Pattern.CASE_INSENSITIVE);
static byte[][] readCertificates(String content, String source) throws CertificateException {
// 实现细节...
}
}
3. 扩展 ClientFactory
ClientFactory 是 Thrifty 客户端的核心工厂类。为了支持 SSL,我们需要对其进行扩展:
public class ClientFactory {
/** SSL参数, 当定义了{@link #socketFactory}参数时无效,不为null时优先使用SSL参数创建SSL Socket连接 */
private XSSLClientConfiguration sslClientConfiguration;
/**
* 设置SSL传输参数<br>
* <p>
* 用于创建SSL Socket连接的参数配置,如果参数为null则不设置
* </p>
* @param xSSLClientConfiguration SSL传输参数实例
* @return 当前对象
* @since 2.6.0
*/
public ClientFactory setSslClientConfiguration(XSSLClientConfiguration xSSLClientConfiguration) {
this.sslClientConfiguration = xSSLClientConfiguration;
return this;
}
/**
* 根据当前配置创建并返回一个已初始化的 {@link SocketTransport} 实例<br>
* <p>
* 若已设置 {@link #sslClientConfiguration},则优先使用 SSL 上下文创建加密连接;<br>
* 否则使用默认 {@link SocketFactory} 创建普通 TCP 连接。
* </p>
* @return 配置完成的 {@link SocketTransport} 实例
*/
private SocketTransport createConfiguredSocketTransport() {
SocketFactory socketFactory = SocketFactory.getDefault();
if (sslClientConfiguration != null) {
try {
SSLContext context = createSSLContextFromPEM(sslClientConfiguration.caFile, null,
sslClientConfiguration.sessionCacheSize, sslClientConfiguration.sessionTimeoutSeconds);
socketFactory = context.getSocketFactory();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return new SocketTransport.Builder(hostAndPort.getHost(), hostAndPort.getPort())
.socketFactory(socketFactory)
.connectTimeout((int) connectTimeout)
.readTimeout((int) readTimeout)
.build();
}
}
使用方法
1. 创建 SSL 配置
首先,您需要创建一个 SSL 配置对象:
XSSLClientConfiguration sslConfig = new XSSLClientConfiguration.Builder()
.caFile(new File("path/to/ca.crt"))
.ciphers(Arrays.asList("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"))
.sessionCacheSize(10000)
.sessionTimeoutSeconds(86400)
.build();
2. 配置 ClientFactory
然后,将 SSL 配置应用到 ClientFactory:
ClientFactory factory = ClientFactory.builder()
.setSslClientConfiguration(sslConfig)
.setHostAndPort("localhost", 9090)
.setTimeout(30, TimeUnit.SECONDS)
.build();
3. 创建客户端实例
最后,使用工厂创建客户端实例:
MyService client = factory.build(MyService.class, MyServiceThriftClient.class);
// 使用客户端
try {
String result = client.myMethod("parameter");
System.out.println("Result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
证书文件格式
支持的证书文件格式:
- PEM 格式的证书文件
- 证书和私钥可以分别存储在不同的文件中,也可以存储在同一文件中
注意事项
- 确保使用强加密套件以保证通信安全
- 生产环境中应使用有效的证书颁发机构签发的证书
- 客户端需要信任服务器的证书颁发机构,或者配置相应的 CA 证书
- 正确配置 SSL 会话缓存大小和超时时间以优化性能
结论
通过扩展 Thrifty 客户端,我们可以轻松地为其添加 SSL/TLS 支持,从而保护客户端与服务器之间的通信安全。这种方法利用了 Java 内置的 SSL 功能,同时保持了 Thrifty 原有的简洁 API。在实际项目中,您可以根据具体需求调整 SSL 配置,以满足安全性和性能要求。
通过这种方式,即使 Thrifty 本身不直接支持 SSL,我们也能构建安全的 RPC 通信,为生产环境中的敏感数据传输提供保障。
完整代码
以上完整代码参见码云仓库:https://gitee.com/l0km/xthrift (ssl 分支)

865

被折叠的 条评论
为什么被折叠?



