- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为我的客户端/服务器应用程序(使用 Netty 库以 Java 编写)创建一个自签名服务器证书。据我了解,我必须创建一个 CA keystore 和一个服务器 keystore ,使用 CA keystore 签署服务器证书并将 CA 证书放在客户端的信任库中。为此,我编写了以下 Windows 脚本:
call keytool -genkey -alias ca -keyalg RSA -keystore ca.keystore -storetype JKS -storepass changeit -keypass changeit
:: create CA keystore
call keytool -exportcert -rfc -alias ca -file truststore.pem -keystore ca.keystore -storepass changeit
:: export CA certificate
call keytool -genkey -alias server -keyalg RSA -keystore server.keystore -storetype JKS -storepass changeit -keypass changeit
:: create server keystore
call keytool -certreq -alias server -keystore server.keystore -file server_signing_request.csr -storepass changeit
:: ask CA to sign server certificate
call keytool -gencert -infile server_signing_request.csr -outfile signed_server_cert.crt -keystore ca.keystore -alias ca -storepass changeit
:: sign server certificate
call keytool -importcert -alias ca -keystore server.keystore -file truststore.pem -storepass changeit
:: import root CA certificate into server keystore
call keytool -import -alias server -keystore server.keystore -trustcacerts -file signed_server_cert.crt -storepass changeit
:: import signed server certificate into server keystore
创建 SSL 引擎的服务器代码:
final KeyStore keyStore;
try (FileInputStream input = new FileInputStream(new File("server.keystore"))) {
keyStore = KeyStore.getInstance("JKS");
keyStore.load(input, "changeit".toCharArray());
}
final KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
factory.init(keyStore, "changeit".toCharArray());
final SSLContext context = SSLContext.getInstance("TLS");
context.init(factory.getKeyManagers(), null, null);
final SSLEngine sslEngine = context.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(false);
并在客户端创建 SslContext:
final SslContext sslContext = SslContextBuilder.forClient().trustManager(new File("truststore.pem")).build();
但是,从客户端到服务器的连接尝试会导致以下异常:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:477)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at de.klenze_kk.chess.client.netty.MyLoggingHandler.channelRead(MyLoggingHandler.java:28)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1339)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1214)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1157)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1048)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:995)
at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1550)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1396)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1237)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1286)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:446)
... 21 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:263)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:276)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1317)
... 35 more
Caused by: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=CA, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" is not a CA certificate
at java.base/sun.security.validator.PKIXValidator.verifyTrustAnchor(PKIXValidator.java:393)
at java.base/sun.security.validator.PKIXValidator.toArray(PKIXValidator.java:333)
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:366)
... 41 more
有人可以帮忙吗?我究竟做错了什么?
最佳答案
看起来您的方向是正确的,但在创建 CA 和服务器证书时缺少几个重要部分。
我建议使用选项 genkeypair
而不是 genkey
而且您还需要一些扩展来为您的证书提供一些额外的功能。
对于 CA,我建议:-ext KeyUsage=digitalSignature,keyCertSign -ext BasicConstraints=ca:true,PathLen:3
对于服务器,我建议:-ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
接下来,您需要确保在将未签名的服务器证书替换为已签名的证书之前将 CA 证书临时导入服务器证书。在我看来,这很奇怪,但 oracle/sun 就是这样设计的。在您的步骤中,您已正确执行此操作,但您可以在导入签名的服务器证书后删除 CA 证书。
您也不需要 -trustcacerts
导入签名的服务器证书时的选项。我建议使用 importcert
而不是 import
导入签名的服务器证书时的命令。
所以总结一下,我建议执行以下步骤:
1.创建CA keystore
keytool -genkeypair -alias ca -keyalg RSA -keystore ca.keystore -storetype JKS -storepass changeit -keypass changeit -ext KeyUsage=digitalSignature,keyCertSign -ext BasicConstraints=ca:true,PathLen:3
2. 创建服务器 keystore
keytool -genkeypair -alias server -keyalg RSA -keystore server.keystore -storetype JKS -storepass changeit -keypass changeit -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
3. 为服务器创建证书签名请求(CSR)
keytool -certreq -alias server -keystore server.keystore -file server_signing_request.csr -storepass changeit -keyalg rsa
4. 使用 CA 签署服务器 CSR
keytool -gencert -infile server_signing_request.csr -outfile signed_server_cert.crt -keystore ca.keystore -alias ca -storepass changeit -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1 -rfc
5.导出CA证书
keytool -exportcert -rfc -alias ca -file truststore.pem -keystore ca.keystore -storepass changeit
6.将CA证书导入服务器 keystore
keytool -importcert -alias ca -keystore server.keystore -file truststore.pem -storepass changeit
7. 导入签名的服务器证书
keytool -importcert -alias server -keystore server.keystore -file signed_server_cert.crt -storepass changeit
8.从服务器 keystore 中删除导入的CA证书
keytool -delete -alias ca -keystore server.keystore -storepass changeit
你能用这些命令重试并分享结果吗?
关于java - 如何修复自签名证书的 "TrustAnchor is not a CA certificate"? ( java ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69413310/
我正在尝试验证我自己生成的证书链,我似乎得到了正确的结果,但我不确定我是否以正确的方式进行验证。 假设我有一个 Intermediate -> Intermediate -> Leaf 链。我不关心根
这个问题在这里已经有了答案: Error - trustAnchors parameter must be non-empty (46 个答案) 关闭 5 年前。
trustAnchors 参数必须为非空 我试图在一周内找到这个异常的解决方案,但我找不到。 我正在运行 JBoss 7.0.13(我们称之为 APP-SV|app.my.site.com),我需要的
我一直在尝试使用 RESTful 服务将文件发送到远程服务器。我得到的只是意外错误:java.security.InvalidAlgorithmParameterException the trust
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我尝试在 Jenkins/Hudson 上配置我的电子邮件,但不断收到错误: java.security.InvalidAlgorithmParameterException: the trustAn
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我经常收到错误: java.security.InvalidAlgorithmParameterException: the trus
我正在尝试在 Jenkins/Hudson 上配置我的电子邮件,但我不断收到错误消息: java.security.InvalidAlgorithmParameterException: the tr
我正在尝试与远程服务器建立安全通信,不幸的是,远程服务器是由他们自己的证书颁发机构签署的。我在这里阅读官方 android 文档:https://developer.android.com/train
我知道这个问题并没有出现很多 stackoverflow,异常(exception)是与丢失的信任库有关 - 但这是我的问题: 在装有 Java 8.0.71 的 Windows 上使用 Apache
我正在尝试与远程服务器建立安全通信,不幸的是,它是自签名的。我在这里阅读官方 android 文档:https://developer.android.com/training/articles/se
我正在尝试通过与服务器的 https 连接验证我的 android 应用程序。 我在尝试进行身份验证时收到以下异常。在查找解决方案时,有很多关于将证书与 apk 绑定(bind)、忽略证书验证等的建议
我正在尝试为我的客户端/服务器应用程序(使用 Netty 库以 Java 编写)创建一个自签名服务器证书。据我了解,我必须创建一个 CA keystore 和一个服务器 keystore ,使用 CA
我正在尝试使用 Railo 3.3 发出 CFHTTP 调用(通过 SSL)并收到以下错误: Unknown host: java.lang.RuntimeException: Unexpected
在有人关闭问题或将其标记为重复之前,我必须说我一直在研究整个互联网,但找不到任何类似的问题。 问题是我在 Virtual Box 镜像中安装了全新的 Linux Mint 19。因此,在安装 Java
我是一名优秀的程序员,十分优秀!