Grpc Java:在服务器上设置 SSLContext

Posted

技术标签:

【中文标题】Grpc Java:在服务器上设置 SSLContext【英文标题】:Grpc Java : Set up SSLContext on Server 【发布时间】:2019-04-02 12:41:42 【问题描述】:

我想在我的 GRPC 服务器上设置 SSL。 为此,我需要证书链和 pkcs8 私钥。

我做了以下事情:

生成 CA 密钥:

openssl genrsa -des3 -out ca.key 4096

生成 CA 证书:

openssl req -new -x509 -days 365 -key ca.key -out ca.crt

生成服务器密钥:

openssl genrsa -des3 -out server.key 4096

生成服务器签名请求:

openssl req -new -key server.key -out server.csr

自签名服务器证书:

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

从服务器密钥中删除密码:

openssl rsa -in server.key -out server.key

转换为 pkcs8

openssl pkcs8 -topk8 -nocrypt -in server.key -out pkcs8_key.pem


现在我有了 server.certpkcs8_key.pem 文件,我已经创建了这样的服务器:

InputStream certChain = MyServer.class.getResourceAsStream("/server.crt");
        InputStream privateKey = MyServer.class.getResourceAsStream("/pkcs8_key.pem");
        SslContext sslContext = GrpcSslContexts.forServer(certChain, privateKey, "password").build();


        Server server = NettyServerBuilder.forPort(8080)
                            .sslContext(sslContext)
                            .addService(new ChatService())
                            .addService(new HelloWorldService())
                            .useTransportSecurity(certChain, privateKey)
                            .build();

类路径配置正确。

我得到的错误堆栈:

Exception in thread "main" java.lang.IllegalArgumentException: Input stream does not contain valid private key.
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:296)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.forServer(SslContextBuilder.java:104)
    at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.forServer(GrpcSslContexts.java:162)
    at server.MyServer.main(MyServer.java:20)
Caused by: java.io.IOException: overrun, bytes = 2353
    at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:92)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.generateKeySpec(SslContext.java:978)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.getPrivateKeyFromByteBuffer(SslContext.java:1034)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.toPrivateKey(SslContext.java:1024)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:294)
    ... 3 more

【问题讨论】:

【参考方案1】:

异常是由这一行引起的:

SslContext sslContext = GrpcSslContexts
    .forServer(certChain, privateKey, "password").build();

由于您的 pkcs8 密钥没有密码,因此您不应传递密码,而应使用双参数方法:

SslContext sslContext = GrpcSslContexts
    .forServer(certChain, privateKey).build();

请注意,调用useTransportSecurity() 将覆盖您对sslContext() 的调用,因此您不应同时调用两者。调用两者都会中断当前代码,因为forServer() 会消耗并关闭提供的InputStreams,因此您会将关闭的流传递给useTransportSecurity()

【讨论】:

谢谢,我不断收到一个新的 java.lang.ClassNotFoundException: org/eclipse/jetty/alpn/ALPN ,尽管我已经编译了 'io.netty:netty-tcnative-boringssl-static:2.0. 6.Final' 在我的 gradle 文件中 试试看github.com/grpc/grpc-java/blob/master/SECURITY.md#netty,尤其是最后的表格

以上是关于Grpc Java:在服务器上设置 SSLContext的主要内容,如果未能解决你的问题,请参考以下文章

grpc-java:正确处理客户端重试以进行服务流调用

Java 开发 gRPC 服务和客户端

gRPC的Java实现

GRPC Java客户端和NodeJS服务器之间的ssl握手问题

java版gRPC实战之七:基于eureka的注册发现

GoLang -- gRPC框架四大服务