Wildfly自动生成的Keystore重启后无法读取报密码错误问题咨询
问题描述
我使用的是升级了Bouncycastle到1.69版本的Wildfly 19.1,具体配置如下:
<security-realm name="SslRealm"> <server-identities> <ssl> <engine enabled-cipher-suites="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" enabled-protocols="TLSv1.2"/> <keystore provider="jks" path=".keystoreFile" relative-to="jboss.server.config.dir" keystore-password="${keystorePassword}" alias="tomcat" key-password="${keystorePassword}" generate-self-signed-certificate-host="localhost"/> </ssl> </server-identities> </security-realm>
${keystorePassword}定义在<system-properties>节点中,密码不含任何特殊字符。
上述SslRealm随后被用于https-listener配置中,首次访问服务端https接口时会自动生成keystore,服务运行一切正常。但停止服务再次启动时,出现如下报错:
2021-09-15 18:42:26,094 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service org.wildfly.core.management.security.realm.SslRealm.key-manager: org.jboss.msc.service.StartException in service org.wildfly.core.management.security.realm.SslRealm.key-manager: Failed to start service at org.jboss.msc@1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1731) at org.jboss.msc@1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1559) at org.jboss.threads@2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982) at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1363) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.lang.IllegalStateException: org.jboss.msc.service.StartException in anonymous service: WFLYDM0018: Unable to start service at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.FileKeyManagerService.loadKeyStore(FileKeyManagerService.java:179) at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.AbstractKeyManagerService.createKeyManagers(AbstractKeyManagerService.java:128) at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.AbstractKeyManagerService.start(AbstractKeyManagerService.java:93) at org.jboss.msc@1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1739) at org.jboss.msc@1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1701) ... 6 more Caused by: org.jboss.msc.service.StartException in anonymous service: WFLYDM0018: Unable to start service at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.FileKeystore.load(FileKeystore.java:153) at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.FileKeyManagerService.loadKeyStore(FileKeyManagerService.java:175) ... 10 more Caused by: java.io.IOException: keystore password was incorrect at java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2116) at java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:243) at java.base/java.security.KeyStore.load(KeyStore.java:1479) at org.jboss.as.domain-management@11.1.1.Final//org.jboss.as.domain.management.security.FileKeystore.load(FileKeystore.java:112) ... 11 more Caused by: java.security.UnrecoverableKeyException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption. ... 15 more
无论我将keystore的provider配置为jks还是pkcs12,或者不配置该参数,都存在此问题。同时使用命令行keytool也无法读取该keystore文件,报错:keytool error: java.io.IOException: keystore password was incorrect
想咨询两个问题:
- 我哪里配置有误导致该问题?
- 我已在standalone.xml中将keystore的provider设为jks,为什么报错信息显示Wildfly尝试以pkcs12格式加载keystore?standalone.xml中是否还有其他位置需要配置keystore的provider?
问题解答
针对第一个问题
你的配置本身没有语法错误,故障根源是BouncyCastle 1.69版本和Wildfly 19自带的自动生成自签名证书逻辑存在兼容性问题:
- 当你配置
generate-self-signed-certificate-host参数后,Wildfly首次收到HTTPS请求时会在内存中生成密钥对和证书,此时使用的是优先级更高的BouncyCastle Provider完成序列化写入磁盘,BC 1.69对JKS/PKCS12格式的存储做了非标准的填充处理,和JDK原生实现不兼容。 - 首次运行时密钥直接从内存加载,所以不会报错;服务重启时需要从磁盘读取keystore,JDK原生解析器无法识别BC生成的存储格式,就会抛出密码错误、填充异常的报错,连keytool也无法读取该文件。
补充说明:Wildfly的自动生成自签名证书特性本来就是面向开发调试场景设计的,没有做第三方安全Provider的兼容性适配,生产环境本来就不建议使用该特性。
针对第二个问题
你配置了provider为jks还是以PKCS12格式加载,有两个原因:
- 你只配置了
provider属性,没有显式配置type属性指定keystore类型。Java 9及以上版本默认的keystore类型为PKCS12,Wildfly的FileKeystore加载逻辑会优先使用JDK默认类型探测文件格式,所以会先尝试用PKCS12解析,解析失败才会尝试JKS格式。 - BouncyCastle注册为安全Provider后优先级高于JDK原生的SUN Provider,即使你指定了provider为jks,BC的密钥解析逻辑还是会优先接管,而BC对JKS的实现和原生SUN Provider的实现不兼容,进一步加剧了格式识别混乱的问题。
standalone.xml中不需要额外配置其他位置的keystore provider,你只需要补全type属性即可指定keystore类型。
解决方案
- 最优方案:取消自动生成自签名证书的配置,提前用JDK原生keytool生成标准JKS/PKCS12格式的keystore文件,再配置到Wildfly中,从根源规避兼容性问题。
- 临时方案1:如果必须使用自动生成证书的特性,在
keystore节点显式添加type="JKS"属性,同时修改JDK安装目录下conf/security/java.security文件,将SUN Provider的优先级调整到BouncyCastle Provider之前,保证keystore的读写都使用JDK原生实现。 - 临时方案2:将BouncyCastle版本回退到1.68,该版本没有调整keystore序列化逻辑,和Wildfly 19不存在兼容性问题。
内容的提问来源于stack exchange,提问作者stmoebius
相关产品推荐
相关产品推荐

