首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gRPC-Java ssl服务器端身份验证证书生成

gRPC-Java ssl服务器端身份验证证书生成
EN

Stack Overflow用户
提问于 2017-11-03 15:48:58
回答 2查看 2.4K关注 0票数 2

我一直试图用ssl为一个简单的gRPC应用程序设置服务器端身份验证。我使用certstrap生成密钥和证书,如下所示:

代码语言:javascript
复制
# Create CA
$ certstrap init --common-name "GRPC"
# Create cert for host using DNS name
$ certstrap request-cert --common-name sdl10236.labs.teradata.com
$ certstrap sign server.com --CA "GRPC"
# gives the following files:
$ GRPC.crl  GRPC.crt  GRPC.key  server.crt  server.csr  server.key

我有下面的java代码,这些代码是我从它们的hello world示例和一些Unit测试中拼凑而成的,因为我找不到如何这样做的完整示例。

代码语言:javascript
复制
private SslProvider sslProvider = SslProvider.OPENSSL;

...

this.clientContextBuilder = GrpcSslContexts.configure(SslContextBuilder.forClient(), this.sslProvider);
try {
    this.serverCertFile = this.loadCert("server.crt");
    this.serverPrivateKeyFile = this.loadCert("server.key");
    this.serverTrustedCaCerts = new X509Certificate[]{this.loadX509Cert("GRPC.crt")};
} catch (IOException ex) {
    logger.warning("Error occurred loading certificate files.");
    ex.getMessage();
    ex.printStackTrace();
} catch (CertificateException cex) {
    logger.warning("Error occurred loading the x509 cert.");
}

...

this.server = serverBuilder(0, this.serverCertFile, this.serverPrivateKeyFile, this.serverTrustedCaCerts).forPort(port).addService(new HelloServiceGrpc.HelloServiceImplBase() { ... }

...

private File loadCert(String name) throws IOException {
    InputStream in = new BufferedInputStream(GrpcServer.class.getResourceAsStream("/certs/" + name));
    File tmpFile = File.createTempFile(name, "");
    tmpFile.deleteOnExit();

    OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
    try {
        int b;
        while ((b = in.read()) != -1) {
            os.write(b);
        }

        os.flush();
    } finally {
        in.close();
        os.close();
    }

    return tmpFile;
}

private X509Certificate loadX509Cert(String fileName) throws CertificateException, IOException {
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    logger.info("" + fileName);
    InputStream in = GrpcServer.class.getResourceAsStream("/certs/" + fileName);
    if (in != null) {
        logger.info("Inputstream is defined.");
    }
    try {
        return (X509Certificate) cf.generateCertificate(in);
    } finally {
        in.close();
    }
}

private ServerBuilder<?> serverBuilder(int port, File serverCertChainFile,
        File serverPrivateKeyFile, X509Certificate[] serverTrustedCaCerts) throws IOException {
    SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(serverCertChainFile, serverPrivateKeyFile);
    GrpcSslContexts.configure(sslContextBuilder, sslProvider);
    sslContextBuilder.trustManager(serverTrustedCaCerts).clientAuth(ClientAuth.REQUIRE);

    return NettyServerBuilder.forPort(port).sslContext(sslContextBuilder.build());
}

当我读取程序中的证书和密钥时,x509证书读取失败。

代码语言:javascript
复制
Exception in thread "main" java.lang.IllegalArgumentException: File does not contain valid private key: /tmp/GRPC.key5252344955683539009
at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:267)
at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:222)
at io.netty.handler.ssl.SslContextBuilder.forServer(SslContextBuilder.java:54)
at com.teradata.grpc.GrpcServer.serverBuilder(GrpcServer.java:152)
at com.teradata.grpc.GrpcServer.start(GrpcServer.java:69)
at com.teradata.grpc.GrpcServer.main(GrpcServer.java:111)
Caused by: java.security.KeyException: could not find a PKCS #8 private key in input stream (see http://netty.io/wiki/sslcontextbuilder-and-private-key.html for more information)
at io.netty.handler.ssl.PemReader.readPrivateKey(PemReader.java:128)
at io.netty.handler.ssl.PemReader.readPrivateKey(PemReader.java:109)
at io.netty.handler.ssl.SslContext.toPrivateKey(SslContext.java:1014)
at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:265)
... 5 more

我真正的问题是什么是生成密钥的正确方法?我已经了解了所有的文档,并且读到了预期的格式是PEM,但是certstrap生成了PEM格式的.crt文件。我不确定我应该在哪些文件中阅读,我也没有在通过生成正确的键来工作的文档中找到和示例。

我应该注意,certstrap生成的密钥在C++中工作,而不是在Java中工作。

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-03 23:32:48

转到错误消息中的URL似乎提供了一个很好的线索:http://netty.io/wiki/sslcontextbuilder-and-private-key.html

certstrap生成以以下开头的键:

代码语言:javascript
复制
-----BEGIN RSA PRIVATE KEY-----

我看到的测试键以:

代码语言:javascript
复制
-----BEGIN PRIVATE KEY-----

运行Netty文档中的命令似乎可以转换成测试键中使用的相同格式:

代码语言:javascript
复制
openssl pkcs8 -topk8 -nocrypt -in server.key -out server.key2

(也在https://groups.google.com/forum/#!topic/grpc-io/5uAK5c9rTHw上讨论)

票数 5
EN

Stack Overflow用户

发布于 2017-11-03 18:32:42

Polyglot有一个进行客户机和服务器TLS auth1的集成测试。它还记录了为了生成certs2而要运行的确切命令。

你应该可以从那里滑动一些代码。这有用吗?

1

2

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47099664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档