新部署的ARM环境报如下异常(更新了JDK到1.8.0.273):
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=rootca, OU=cn, O=ww, L=hz, ST=zj, C=cn" is not a CA certificate
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:643)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:566)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=rootca, OU=cn, O=ww, L=hz, ST=zj, C=cn" is not a CA certificate
at sun.security.ssl.Alert.createSSLException(Alert.java:131)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkClientCerts(CertificateMessage.java:698)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:409)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:373)
at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376)
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
at sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:983)
at sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:970)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:917)
at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1167)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1080)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:950)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
... 16 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=rootca, OU=cn, O=ww, L=hz, ST=zj, C=cn" is not a CA certificate
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:263)
at sun.security.validator.Validator.validate(Validator.java:271)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:275)
at sun.security.ssl.X509TrustManagerImpl.checkClientTrusted(X509TrustManagerImpl.java:134)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkClientCerts(CertificateMessage.java:680)
... 28 more
Caused by: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=rootca, OU=cn, O=hw, L=hz, ST=zj, C=cn" is not a CA certificate
at sun.security.validator.PKIXValidator.verifyTrustAnchor(PKIXValidator.java:393)
at sun.security.validator.PKIXValidator.toArray(PKIXValidator.java:333)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:366)
... 34 more
问题根因:
更新了JDK之后,jdk对CA证书的校验更加严格,若未明文标识该证书是CA证书,则会出现异常。
解决办法:
1. 规避措施:
应用程序启动时,在启动参数里加上如下参数,不进行校验是否为CA
-Djdk.security.allowNonCaAnchor=true
2. 根本解决方法:
在生成CA证书时明确添加是否为CA的标识-ext BasicConstraints=ca:true
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
说明:
两种方法各有优缺,请根据实际情况选择,方法1操作简单,且无需替换证书,但不检验CA证书不安全,方法2从根本上解决了该问题,但需要更换证书,若涉及app客户端等,则需要重装。