使用SSL的Java / Spring UnrecoverableKeyException

时间:2014-06-18 07:41:47

标签: java spring ssl keytool

请注意:虽然这个具体问题涉及Ldaptive库,但我坚信它纯粹是一个Java keytool / SSL / Spring问题。

我在我的Java(Spring)应用服务器上使用Ldaptive来针对LDAP / AD服务器对用户进行身份验证。当我将WAR部署到Tomcat并启动它时,我得到以下异常:

    (Large stack trace above this, below is the root exception)
    ... 70 more
Caused by: java.security.UnrecoverableKeyException: requested entry requires a password
    at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:459)
    at java.security.KeyStore.getEntry(KeyStore.java:1290)
    at org.ldaptive.ssl.KeyStoreUtils.getEntry(KeyStoreUtils.java:129)
    at org.ldaptive.ssl.KeyStoreSSLContextInitializer.createTrustManagers(KeyStoreSSLContextInitializer.java:116)
    at org.ldaptive.ssl.AbstractSSLContextInitializer.getTrustManagers(AbstractSSLContextInitializer.java:41)
    at org.ldaptive.ssl.AbstractSSLContextInitializer.initSSLContext(AbstractSSLContextInitializer.java:84)
    at org.ldaptive.ssl.TLSSocketFactory.initialize(TLSSocketFactory.java:68)
    at org.ldaptive.provider.jndi.JndiProvider.getJndiStartTLSConnectionFactory(JndiProvider.java:162)
    ... 83 more

错误来自这个Spring bean:

<bean id="sslConfig" class="org.ldaptive.ssl.SslConfig">
    <property name="credentialConfig">
        <bean class="org.ldaptive.ssl.KeyStoreCredentialConfig"
            p:keyStore="file:/etc/myapp/keys.jks"
            p:keyStorePassword="password"
            p:keyStoreType="JKS"
            p:keyStoreAliases="kw-dj93d3j9-29kd-dj9k-dkow-dk3jd93jsjs8" />
    </property>
</bean>

正如您所看到的,我告诉Ldaptive在/etc/myapp下查看我的本地文件系统,找到名为keys.jks的Java KeyStore。在这个密钥库中有一个名为&#34; kw-dj93d3j9-29kd-dj9k-dkow-dk3jd93jsjs8 &#34;。

当我使用keytool检查此密钥时:

cd /etc/myapp
keytool -list -keystore keys.jks
Enter keystore password:  password

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

kw-dj93d3j9-29kd-dj9k-dkow-dk3jd93jsjs8, May 1, 2014, PrivateKeyEntry,
Certificate fingerprint (SHA1): <Long hexidecimal strings here...>

值得一提的是,不是自签名证书。这是来自信誉良好的CA的证书。

所以我知道密钥位于密钥库中。但是,我似乎记得当我将这个密钥添加到JKS(几个月前)时,密钥本身就有密码(我还设置为&#34;密码&#34; )。但是,我尝试使用keytool进行搜索,看看我是否可以让它向我询问密钥/别名的个人密码(而不是商店密码)和我无法重现这一点,但只是值得深思。如果我不得不猜测,Spring bean中的keyStorePassword字段是正确的,但密钥本身需要密码,而Ldaptive并没有考虑到这一点......

无论如何,有什么想法为什么我会看到这个例外?如果我是正确的,而且我无法更改Ldaptive的源代码,那么我的选择是什么?是否有keytool个命令可用于删除单个密钥的密码,只接受商店范围的密码?

3 个答案:

答案 0 :(得分:1)

堆栈跟踪似乎与您发布的配置不匹配。具体做法是:

at org.ldaptive.ssl.KeyStoreSSLContextInitializer.createTrustManagers(KeyStoreSSLContextInitializer.java:116)
at org.ldaptive.ssl.AbstractSSLContextInitializer.getTrustManagers(AbstractSSLContextInitializer.java:41)

正在配置信任管理员,而不是密钥管理员。我希望这个配置会出现异常:

    <bean class="org.ldaptive.ssl.KeyStoreCredentialConfig"
        p:trustStore="file:/etc/myapp/keys.jks"
        p:trustStorePassword="password"
        p:trustStoreType="JKS"
        p:trustStoreAliases="kw-dj93d3j9-29kd-dj9k-dkow-dk3jd93jsjs8" />

尽管如此,如果您发现了错误,请提出问题here

答案 1 :(得分:0)

从命令行,您应该能够通过将密钥导出到PKCS12并使用OpenSSL [线程here]中的说明进行检查来验证密钥是否仍具有密码。当然,该线程还指出了一个免费的GUI工具,它似乎允许您直接编辑JKS,如果您习惯使用它可能会更简单。

最糟糕的情况是,您始终可以生成一个新的自签名进行测试,以验证问题与JKS有关,而不是配置/环境中的问题。

答案 2 :(得分:0)

由于异常说“要求密码”而不是“无法恢复”我很确定Ldaptive是在没有密码而不是错误密码的情况下调用getEntry。私钥条目总是需要密码,所以这是Ldaptive代码或配置,我希望后者更有可能,FWLTW。

假设“添加此密钥”意味着使用-genkeypair(或更早的等效-genkey)生成,该操作会单独提示(在主题名称对话框之后)以获得可用的每密钥密码与商店密码不同,但默认情况下(如果你点击返回)是相同的。 AFAICS是唯一需要并因此提示现有条目上的密钥密码的keytool选项是-keypasswd -certreq-importkeystore,其中第一个是更改密码的方法。所以运行(任何排序)

keytool -keystore $file -keypasswd -alias $name 

如果它提示您输入“输入密钥密码”,则该条目的密钥密码与商店密码不同。如果它立即提示“新密钥密码”,则密钥密码当前是商店密码;只是控制-C出来。如果有一个独特的密钥密码,你不记得或猜测它你运气不好;你需要打破加密,虽然我没有看到JKS究竟使用了什么,但我相信它非常强大。

您的问题没有必要,但这是一个非常有趣的别名。如果它具有一定的意义,你不需要保密,我不介意知道。