简体   繁体   English

创建用于 Netty Websocket 服务器的自签名证书

[英]Create self-signed certificate for usage with Netty Websocket Server

I am trying to create self-signed certificate for usage with a Netty (4.1.86) Websocket Server.我正在尝试创建用于 Netty (4.1.86) Websocket 服务器的自签名证书。 It's running fine without SSL as well as with a certificate created with the SelfSignedCertificate class. But I am struggling when creating a self signed certificate with openssl.它在没有 SSL 以及使用 SelfSignedCertificate class 创建的证书的情况下运行良好。但是我在使用 openssl 创建自签名证书时遇到了困难。

This:这个:

SslContext sslCtx = SslContextBuilder.forServer(new File(certFile), new File(keyFile), password).build();

Throws the following error:抛出以下错误:

ERROR Thread-5 com..application.NettyWSServer - Exception caught:
java.lang.IllegalArgumentException: File does not contain valid private key: /home/johnny/testbench/application/app.pkcs8.key
        at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:386)
        at io.netty.handler.ssl.SslContextBuilder.forServer(SslContextBuilder.java:120)
        at com..application.NettyWSServer.start(NettyWSServer.java:78)
        at com..application.ApplicationLauncher$2.run(ApplicationLauncherncher.java:315)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.security.NoSuchAlgorithmException: 1.2.840.113549.1.5.13 SecretKeyFactory not available
        at java.base/javax.crypto.SecretKeyFactory.<init>(SecretKeyFactory.java:122)
        at java.base/javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:168)
        at io.netty.handler.ssl.SslContext.generateKeySpec(SslContext.java:1084)
        at io.netty.handler.ssl.SslContext.getPrivateKeyFromByteBuffer(SslContext.java:1170)
        at io.netty.handler.ssl.SslContext.toPrivateKey(SslContext.java:1133)
        at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:384)
        ... 4 more

Here's how I create certFile (app.pem) and keyFile (app.pkcs8.key):以下是我创建certFile (app.pem) 和keyFile (app.pkcs8.key) 的方法:

openssl genrsa -out app.key 2048

openssl pkcs8 -topk8 -in app.key -out app.pkcs8.key

openssl req -x509 -new -nodes -key app.key -sha256 -days 1024 -out app.pem

As per my understanding Netty needs a pkcs8 format key:根据我的理解,Netty 需要一个 pkcs8 格式的密钥:

https:/.netty.io/4.1/api/io.netty/handler/ssl/SslContextBuilder.html#forServer-java.io.File-java.io.File- https:/.netty.io/4.1/api/io.netty/handler/ssl/SslContextBuilder.html#forServer-java.io.File-java.io.File-

Working solution thanks to dave_thompson_085 :感谢dave_thompson_085的工作解决方案:

openssl genrsa -out app.key 2048

openssl pkcs8 -topk8 -v1 PBE-SHA1-3DES -nocrypt -in app.key -out app.pkcs8.key

openssl req -x509 -new -nodes -key app.key -sha256 -days 1024 -out app.pem

More exactly the default SSLContext path needs either PKCS8-unencrypted or PKCS8-encrypted using a password-based encryption (PBE) scheme that is defined uniquely by the OID at the beginning of the AlgorithmIdentifier, like the schemes in PKCS5v1 (now retronymed PBES1) or PKCS12, but not the newer/better family of schemes in PKCS5v2 named PBES2, because the OID for PBES2 -- 1.2.840.113549.1.5.13 which you see in your exception message -- does not identify a single scheme and thus is not sufficient for Java to instantiate a SecretKeyFactory (causing the exception).更确切地说, 默认SSLContext路径需要 PKCS8 未加密或 PKCS8 加密,使用基于密码的加密 (PBE) 方案,该方案由 AlgorithmIdentifier 开头的 OID 唯一定义,如 PKCS5v1 中的方案(现在改名为 PBES1)或PKCS12,但不是 PKCS5v2 中名为 PBES2 的更新/更好的方案系列,因为 PBES2 的 OID——您在异常消息中看到的 1.2.840.113549.1.5.13——没有标识单个方案,因此是不够的对于 Java 实例化一个SecretKeyFactory (导致异常)。 And openssl pkcs8 -topk8 by default uses a PBES2 scheme since 1.1.0 in 2016. openssl pkcs8 -topk8自 2016 年 1.1.0 以来默认使用 PBES2 方案。

But the.netty 4.1 SSLContext.toPrivateKey method(s) (which you can see and your stacktrace confirms SSLContextBuilder calls) will instead use BouncyCastlePemReader if available, and Bouncy can handle both older PBE schemes and PBES2, and also OpenSSL 'traditional' format files that are not PKCS8 at all (and if/when encrypted use a scheme based on OpenSSL's own PBKDF EVP_BytesToKey ).但是.netty 4.1 SSLContext.toPrivateKey方法(你可以看到,你的堆栈跟踪确认SSLContextBuilder调用)将改为使用BouncyCastlePemReader如果可用),Bouncy 可以处理旧的 PBE 方案和 PBES2,以及 OpenSSL“传统”格式文件根本不是 PKCS8(如果/加密时使用基于 OpenSSL 自己的 PBKDF EVP_BytesToKey的方案)。

Thus I think (but can't test) you have 3 options:因此我认为(但无法测试)您有 3 个选择:

  1. supply BouncyCastle .供应充气城堡 I think you need bcprov (or bcprov-ext) and bcpkix;我认为您需要 bcprov(或 bcprov-ext)和 bcpkix; you may now need bcutil (due to a reorg in recent versions I haven't fully grokked).您现在可能需要 bcutil(由于最近版本的重组,我还没有完全理解)。

  2. encrypt your file with a non-PBES2 scheme.使用非 PBES2 方案加密您的文件。 The PBES1 schemes are all now broken or easily breakable; PBES1 方案现在都已被破坏或很容易被破坏; the 'best' (least bad) PKCS12 scheme is officially named pbeWithSHA1And3-KeyTripleDES-CBC (:) but OpenSSL has a more convenient 'shortname': “最好的”(最不坏的)PKCS12 方案正式命名为pbeWithSHA1And3-KeyTripleDES-CBC (:) 但 OpenSSL 有一个更方便的“简称”:

    openssl pkcs8 -topk8 -v1 PBE-SHA1-3DES [-in oldfile -out newfile]

    Technically you could also accomplish this by leaving the default on a very old version of OpenSSL, but that's usually more difficult(*) and in my view not really different.从技术上讲,您也可以通过将默认值保留在非常旧的版本 OpenSSL 上来实现这一点,但这通常更困难 (*),而且在我看来并没有什么不同。 (* not for me, because I have my own archive of old versions, but I'm weird) (* 不适合我,因为我有自己的旧版本存档,但我很奇怪)

  3. don't encrypt your keyfile, (only,) if you can adequately secure it otherwise.不要加密你的密钥文件,(仅)如果你能以其他方式充分保护它。 for example by access controls on your system(s) (and any backups): Use:例如通过对您的系统(和任何备份)的访问控制:使用:

    openssl pkcs8 -topk8 -nocrypt [-in oldfile -out newfile]

    or a bit more simply:或者更简单一点:

    openssl pkey [-in oldfile -out newfile]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM