Ktor使用PEM转换的keystore.jks配置HTTPS失败,报BadPaddingException错误求助
问题描述
我在搭建嵌入式Ktor服务器时想要启用HTTPS,但配置后启动报错:
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
我用以下命令将PEM证书转换为JKS格式:
openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name “miAlias” keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks
服务器加载证书的代码如下(错误发生在启动阶段):
val keyStoreFile = File("resources/keystore.jks") val keyStoreIn = FileInputStream("resources/keystore.jks") val keyStorePass = "****".toCharArray() val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()) keyStore.load(keyStoreIn, keyStorePass) log.debug("keystore=${KeyStore.getDefaultType()}") // pkcs12 log.debug("mialias=${keyStore.containsAlias("miAlias")}") // true val environment = applicationEngineEnvironment { connector { port = config.httpPort } sslConnector( keyStore = keyStore, keyAlias = "miAlias", keyStorePassword = {"******".toCharArray()}, privateKeyPassword = {"******".toCharArray()} ) { port=8443 keyStorePath=keyStoreFile } module { ... } } val server = embeddedServer(Netty, environment).start(wait = true)
服务器在不启用HTTPS时运行正常,启用后就出现上述错误,现在有点迷茫,求大佬指点!
问题排查与解决方案
兄弟,这个报错十有八九是密钥、密码或者别名的配置不一致导致的,我给你梳理几个最可能的排查方向,你挨个试试:
优先检查别名的引号问题!
你看openssl命令里的-name “miAlias”用的是中文双引号,这会导致生成的别名不是miAlias,而是包含中文引号的内容(或者系统识别异常)。赶紧改成英文双引号"miAlias",重新执行转换命令生成新的keystore,这是最容易踩的低级坑,很多人输入法切换不注意就中招了。确认所有密码完全一致
- 执行
openssl pkcs12 -export时会要求输入导出密码,这个密码要和keytool转换时的源密码(如果没指定-srcstorepass就是你手动输入的那个)完全一致,同时也要和Ktor代码里的keyStorePassword、privateKeyPassword对应上。 - 如果你的
key.pem本身没有设置密码,那privateKeyPassword要和keystore密码保持一致;如果key.pem有独立密码,那这里要填私钥的密码,别搞混了。
- 执行
检查Keystore加载的细节
- 你代码里
KeyStore.getDefaultType()输出是pkcs12,虽然没问题,但可以尝试明确指定类型为JKS:KeyStore.getInstance("JKS"),毕竟你最终生成的是.jks文件,明确类型可能避免一些兼容问题。 - 加个文件存在性判断,确保读取的是正确的keystore文件:
if (!keyStoreFile.exists()) { log.error("Keystore file not found at path: ${keyStoreFile.absolutePath}") }
- 你代码里
验证Keystore的有效性
用keytool命令查看keystore的详细信息,确认别名和私钥条目是否正确:keytool -list -v -keystore keystore.jks输入密码后,检查输出里是否有
miAlias的条目,且类型为PrivateKeyEntry,如果别名不对或者没有私钥,那肯定会报错。
先从别名的问题入手,这个概率最大,重新生成keystore后再检查密码,应该就能解决问题了!
备注:内容来源于stack exchange,提问作者user3810191

