gRPC:如何在客户端配置 SSL?

gRPC: How to configure SSL in client?

这对我来说是个新话题。我能够以明文形式连接。

public ManagedChannel getChannel(String serviceName){
    TSServiceClientManager scm = TSServiceManagementFactory.getInstance().getServiceClientManager();
    TSServiceConnectionInfo connInfo = scm.getServiceConnectionInfo(serviceName);
    if(channel == null){
        channel = ManagedChannelBuilder.forAddress(connInfo.getHost(), connInfo.getPort())
                .usePlaintext(true) //need help here for SSL code 
                .build();
    }

    return channel;
}

有人告诉我启用客户端 SSL。我知道如何生成密钥库、信任库、pem、CA 等。 我需要帮助:

如何启用 SSL 而不是上面代码中所示的 .usePlaintext(true)?

(考虑到证书文件、密钥库、信任库和 .pem 文件存在,请重写代码)

我想知道与服务器有什么关系才能使 SSL 连接正常工作吗?

从 grpc-java 1.37.0 开始,大多数用户可以在不使用传输特定 APIs 的情况下配置 TLS。这利用了 1.34.0 中引入的 ChannelCredentials 概念。

ChannelCredentials creds = TlsChannelCredentials.newBuilder()
    // if server's cert doesn't chain to a standard root
    .trustManager(caFile)
    .keyManager(clientCertFile, keyFile) // client cert
    .build();
channel = Grpc.newChannelBuilderForAddress(serverHost, serverPort, creds)
    .build();

TlsServerCredentialsGrpc.newServerBuilderForPort() 将在服务器端使用。

高级用例可能需要使用传输特定的 APIs,例如 GrpcSslContextsNettyChannelBuilder.sslContext()


原始答案:您需要使用特定于传输的 API。您今天可能正在使用 Netty。对于 Netty,需要配置 Netty 的 SslContext 并传递给 gRPC。您的用法可能如下所示:

SslContext sslcontext = GrpcSslContexts.forClient()
    // if server's cert doesn't chain to a standard root
    .trustManager(caFile)
    .keyManager(clientCertFile, keyFile) // client cert
    .build();
channel = NettyChannelBuilder.forAddress(serverHost, serverPort)
    .sslContext(sslContext)
    .build();

如果需要服务器端配置,就用类似的NettyServerBuilder.sslContext()。但上下文本身会有所不同。

如果有人想使用 JKS 文件,那么下面的代码可能会有所帮助。

InputStream is = Utils.class.getClassLoader().getResourceAsStream("truststore.jks");
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(is, "secret".toCharArray());

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(truststore);

SslContextBuilder sslContextbuilder = GrpcSslContexts.forClient().trustManager(trustManagerFactory);
SslContext sslContext = sslContextbuilder.build();
channel = NettyChannelBuilder.forAddress("localhost", "8443").sslContext(sslContext).build();