我想在我的 GRPC 服务器上设置 SSL。 为此,我需要证书链和一个 pkcs8 私钥。
我做了以下事情:
生成CA key :
openssl genrsa -des3 -out ca.key 4096
生成CA证书:
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
生成服务器 key :
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
从服务器 key 中删除密码:
openssl rsa -in server.key -out server.key
转换为 pkcs8
openssl pkcs8 -topk8 -nocrypt -in server.key -out pkcs8_key.pem
现在我有了 server.cert 和 pkcs8_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
最佳答案
异常是由这一行引起的:
SslContext sslContext = GrpcSslContexts
.forServer(certChain, privateKey, "password").build();
由于您的 pkcs8 key 没有密码,因此您不应传递密码,而应使用双参数方法:
SslContext sslContext = GrpcSslContexts
.forServer(certChain, privateKey).build();
请注意,调用 useTransportSecurity()
将覆盖对 sslContext()
的调用,因此您不应同时调用两者。调用两者会中断当前代码,因为 forServer()
消耗并关闭提供的 InputStream
,因此您会将关闭的流传递给 useTransportSecurity()
.
关于java - GRPC Java : Set up SSLContext on Server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53047940/