【问题标题】:Key error when I import new certificate to old keystore - java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 48)将新证书导入旧密钥库时出现密钥错误 - java.io.IOException: ObjectIdentifier() -- 数据不是对象 ID (tag = 48)
【发布时间】:2022-01-24 08:20:43
【问题描述】:

所以我有这个旧的密钥库 (mykeystore.p12) 和一个现在任何一天都会过期的证书 + 一些我需要保留的其他密钥。

然后我从我的 CA 获得了这个新的 certificate.txt + privatekey.txt + bundle.txt。根据我的发现,我需要将所有这些文件导入新的密钥库,然后将新的密钥库导入我的旧密钥库。 (我尝试立即将其导入旧密钥库,但它覆盖了旧存储)。

所以要创建新的密钥库,我这样做:

openssl pkcs12 -export -in certificate.txt -inkey privatekey.txt -out newkeys.p12 -name com -CAfile bundle.txt -caname root

newkeys.p12 如果我尝试使用它就可以工作,但它丢失了我仍然需要的所有旧密钥,因此将其导入我当前的旧密钥库(工作正常但证书过期)我这样做:

keytool -importkeystore -deststorepass PASSWORD -destkeystore mykeystore.p12 -srckeystore newkeys.p12 -srcstoretype PKCS12 -srcstorepass PASSWORD -alias com

但是后来一切都停止了,我什至无法启动我的 web 应用程序,因为我收到了这个错误:

at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:934) ~[spring-context-5.3.4.jar!/:5.3.4]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:585) ~[spring-context-5.3.4.jar!/:5.3.4]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.3.jar!/:2.4.3]
        at com.aquaass.aquadb.AquaassApplication.main(AquaassApplication.java:17) [classes!/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_275]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_275]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_275]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_275]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [aquadb.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:107) [aquadb.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [aquadb.jar:na]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) [aquadb.jar:na]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Jetty server
        at org.springframework.boot.web.embedded.jetty.JettyWebServer.start(JettyWebServer.java:194) ~[spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle.start(WebServerStartStopLifecycle.java:43) ~[spring-boot-2.4.3.jar!/:2.4.3]
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.4.jar!/:5.3.4]
        ... 23 common frames omitted
Caused by: java.security.UnrecoverableKeyException: Private key not stored as PKCS#8 EncryptedPrivateKeyInfo: java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 48)
        at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:338) ~[na:1.8.0_275]
        at java.security.KeyStore.getKey(KeyStore.java:1023) ~[na:1.8.0_275]
        at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:145) ~[na:1.8.0_275]
        at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70) ~[na:1.8.0_275]
        at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256) ~[na:1.8.0_275]
        at org.eclipse.jetty.util.ssl.SslContextFactory.getKeyManagers(SslContextFactory.java:1243) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.ssl.SslContextFactory$Server.getKeyManagers(SslContextFactory.java:2267) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.ssl.SslContextFactory.load(SslContextFactory.java:372) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.ssl.SslContextFactory.doStart(SslContextFactory.java:243) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.server.SslConnectionFactory.doStart(SslConnectionFactory.java:97) ~[jetty-server-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:321) ~[jetty-server-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81) ~[jetty-server-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:234) ~[jetty-server-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.springframework.boot.web.embedded.jetty.SslServerCustomizer$SslValidatingServerConnector.doStart(SslServerCustomizer.java:265) ~[spring-boot-2.4.3.jar!/:2.4.3]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73) ~[jetty-util-9.4.36.v20210114.jar!/:9.4.36.v20210114]
        at org.springframework.boot.web.embedded.jetty.JettyWebServer.start(JettyWebServer.java:174) ~[spring-boot-2.4.3.jar!/:2.4.3]
        ... 25 common frames omitted
Caused by: java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 48)
        at sun.security.util.ObjectIdentifier.<init>(ObjectIdentifier.java:285) ~[na:1.8.0_275]
        at sun.security.util.DerInputStream.getOID(DerInputStream.java:320) ~[na:1.8.0_275]
        at com.sun.crypto.provider.PBES2Parameters.engineInit(PBES2Parameters.java:267) ~[sunjce_provider.jar:1.8.0_275]
        at java.security.AlgorithmParameters.init(AlgorithmParameters.java:293) ~[na:1.8.0_275]
        at sun.security.x509.AlgorithmId.decodeParams(AlgorithmId.java:137) ~[na:1.8.0_275]
        at sun.security.x509.AlgorithmId.<init>(AlgorithmId.java:119) ~[na:1.8.0_275]
        at sun.security.x509.AlgorithmId.parse(AlgorithmId.java:393) ~[na:1.8.0_275]
        at sun.security.pkcs.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:80) ~[na:1.8.0_275]
        at sun.security.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:327) ~[na:1.8.0_275]
        ... 46 common frames omitted

起初我认为私钥之间可能存在一些冲突,它们的格式不同,因此存在一些冲突或其他东西(因为它们只有在它们都在同一个密钥库中时才不起作用),但是看来它们都是 RSA 2048。所以现在我必须认为我输入错误了,但根据我的在线研究,这是这样做的,所以我很难过,有点急于解决这个问题。我的 CA 足以生成一个新证书,但仍然存在同样的问题,所以我倾向于导入出错或其他什么。

如果我将新密钥库导入到我的旧密钥库或其他方式似乎并不重要,仍然是同样的问题。为什么我会收到此错误?请帮忙!

编辑 1: 现在我什至尝试在我自己的工作密钥库中生成一个新的密钥对(99% 确信我确实像去年那样做了),然后导出了一个签名请求 (.csr)我签了。然后我将新的签名证书和捆绑包导入到该密钥对别名,但仍然出现同样的错误!

Command for generating new keypair and cert:
keytool -genkey -alias com -keystore mykeystore.p12 -storetype PKCS12 -keyalg RSA -storepass PASSWORD -validity 366 -keysize 2048

Command for exporting csr:
keytool –keystore mykeystore.p12 –certreq –alias com –keyalg rsa –file sign-request.csr

编辑 2: 不同阶段的密钥库信息:

mykeystore.p12 -info:
MAC Iteration 100000
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000
Certificate bag
Certificate bag
Certificate bag
Certificate bag


newkey.p12 -info:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048


merged mykeystore.p12 -info:
MAC Iteration 100000
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000
Certificate bag
Certificate bag
Certificate bag
Certificate bag
Certificate bag

And this is the original keystore (from edit 1) where I created the keys
+ csr and imported signed cert (I thought I generated the keys the same 
way as last year but it appears maybe not):

MAC Iteration 100000
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000
Certificate bag
Certificate bag
Certificate bag
Certificate bag
Certificate bag
Certificate bag
Certificate bag
Certificate bag

编辑 3:

java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)

【问题讨论】:

  • 你使用的是什么版本的keytool?如果这足够新,也许和/或如果您使用的是 OpenSSL 3.0.x,那么 PKCS12 中的加密使用 PBES2,并且 8u275 有一个无法处理它的错误。在*.com/questions/70244066/… 上查看(我的)链接和摘要。
  • 感谢您的链接,我会检查出来!我的 Keytool 版本是 8.0.2410.7。我不知道如何检查我的 openssl 版本
  • 那是Windows .exe 版本? Java 版本实际上是:premodular(和你的一样) 1.v.0 update u,通常省略 1. 和 .0,v 1 到 8,并且 update 通常缩写为 u 或 _;或用于 v 9 及更高版本的模块化后 v.0.u 和 .0.0 被抑制。如果没有人搞砸,你的是 8u241,我在一个旧的测试系统上使用它,它甚至不会使用 PBES2 输入执行-importkeystore,这将避免 OpenSSL 版本,但你可以通过运行来获得它@ 987654330@,如果您使用的是 Shininglight 构建,它还具有 Windows .exe 属性,就像您的 keytool 一样。 ...
  • ...无论如何,在mykeystore.p12 输入到keytool(假设您保存或可以恢复副本)和输出上,请执行openssl pkcs12 -in $file -nokeys -nocerts -info 并显示结果。
  • 是的,使用 PBES2 加密的“包”正是问题所在——但 8u241 中的 keytool 应该无法创建此类,除非将标准提供程序替换为 very奇怪的。您确定您在该机器上没有另一个更新的 Java 可以调用,可能作为 IDE 或 SDK 或其他东西的一部分? where keytool 是否指向任何意想不到的地方?为 -importkeystore 为 -genkeypair,-certreq,-import(reply) 创建 PBES2 肯定与 8u301 或更高版本一致。

标签: spring-boot openssl keystore private-key keytool


【解决方案1】:

好的,它终于证明你在 Windows 上并试图移动和更改已安装 Java 的部分。由于您显然拥有更新程序,因此我假设您使用了 Oracle 可执行安装程序(用于 JRE,或用于包含“公共”JRE 的 JDK),而不是用于 JRE 或 Server-JRE 的 tgz“安装程序”(实际上只是一个存档)。

不支持复制 Java 片段,尤其是在 Windows 上。 Java 实用程序(如 keytool rmid javac jar jlink jconsole)在 Windows 上以 .exe 文件的形式提供,但它们不包含实际功能,它们只是加载和运行 Java 代码以执行实际功能的存根,并且在至少在 Windows 上,此代码有时可能不在同一目录中,而是通过注册表找到,该注册表记录安装程序放置它的位置,而不是您所做的任何手动更改。

我怀疑Java 更新程序(不是 Windows 的一部分)至少尝试安装 8u301 或更高版本的更新,结果您现在正在运行有点像 Franken-Java,其中包含至少两个不同版本的部分,因此基本上不可能准确预测或理解它在做什么。 您可能会查看控制面板/程序和功能(又名appwiz.cpl)以查看安装时记录的内容,但如果您手动更改了内容,则此记录可能不正确/不完整。

我认为你有 4 个选择:

  • 将此机器恢复为低于 8u301 的单个正确 Java 版本。鉴于您的模糊描述,我有信心的唯一方法是删除您现在拥有的所有内容并从头开始。 (IIRC 您实际上不能从 .exe 安装程序中排除更新程序,但您可以禁用它,以防止它再次让您回到同样的混乱状态。或者可能使用没有 的 tgz 软件包之一 更新程序。)如果您在使用标准安装的 Java 时遇到问题,您可能想询问那个;我没有,而且我看到其他人提出的问题很少,并且鉴于 Java 其他方面的许多问题,这强烈表明标准安装适用于许多人。

  • 使用具有或在其上获得低于 8u301 的正确版本的其他机器。运行该应用程序的机器显然有 8u275,这可能是 OpenJDK 版本,因为除了 271 之外似乎没有 Oracle 27x 版​​本的记录;也许你可以使用它。在 Win 10 上,您可以使用 WSL,它实际上是一个(小型、方便的)虚拟机(如果您不想保留它,您可以在之后删除它)。

  • 如果可以接受非标准和稍低的安全性,请使用 JKS 格式而不是 PKCS12。 Java 对 JKS 的支持没有像 PKCS12 那样改变,所以即使是混合的 Java 也应该产生可用的 JKS。

  • 将运行应用程序的机器(或环境,例如容器)升级到 8u301 或更高版本——甚至可能是 11 或 17,但 Spring 在迁移到模块化 Java 时可能存在问题——因此它可以处理 PBES2。这是最好的长期解决方案; Java 正在顺应行业趋势,尽管并非一致,但会向更好的安全性迈进,如果您坚持过去,您最终(可能会突然)遇到越来越多的此类问题。

【讨论】:

  • 你可能是对的。但是如果我删除了我移动到我的“workshop”文件夹中的 2 个文件,其余的应该是“default”吗?起初我确实尝试将 keytool 设置为路径,但它似乎不起作用,但正如我所提到的,它现在可以工作,这使得这个“workshop”文件夹复制变得不必要。也许我应该考虑在 Spring Boot 上运行 Java 11,但我在我的 android 应用程序上使用 Java 8,这是我最习惯的,我认为升级到 Java 11 意味着很多工作和变化谢谢你的帮助!
  • 您说更新程序安装了新版本,或者尝试了。即使您回到 8u241 的原始路径,正如我所说,我不相信您会获得 一致 8u241。我想到了一件你可以检查的事情:试试[path\to\]keytool -J-version;如果那是错误的,它肯定可以解释问题,尽管如果它是正确的,那么在 Java 中可能仍然存在一些其他混淆。你不需要11来解决这个问题,8u301就足够了(正如我所说); 11 或 17 只是一个选项,如果您出于其他原因不想要它也没关系。
  • 我将结果添加到“编辑 3”。我从 oracales 更新助手获得的更新是我为其他项目安装的 jre1.8.0_311。我相信你是对的,我的电脑上的安装可能不正确,因为这可以解释很多
最近更新 更多