19

我通过复制我计划连接的 IDP 的 509 条目生成了 testIdp.cer 文件。然后我通过执行以下命令创建了 JKS 文件

keytool -importcert -alias adfssigning -keystore C:\Users\user\Desktop\samlKeystore.jks -file    C:\Users\user\Desktop\testIdp.cer

执行时,它要求输入我已提供密码的密码。对于“信任此证书?[否]:”这个问题,我给出了“y”作为输入。消息显示为“证书已添加到密钥库”。

然后我在securityContext.xml中配置了以下细节

<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:security/samlKeystore.jks"/>
    <constructor-arg type="java.lang.String" value="mypassword"/>
    <constructor-arg>
        <map>
            <entry key="adfssigning" value="mypassword"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="adfssigning"/>
</bean>

<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
  <property name="alias" value="adfssigning" />
  <property name="signingKey" value="adfssigning"/>     
</bean>

但是当我运行应用程序时,在服务器启动和加载应用程序主页时出现以下两个异常。任何人都可以让我知道我是否缺少其他任何东西。

启动服务器时发生此异常

Caused by: org.opensaml.saml2.metadata.provider.FilterException: Signature trust establishment failed for metadata entry
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.verifySignature(SignatureValidationFilter.java:327)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.processEntityGroup(SignatureValidationFilter.java:240)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.doFilter(SignatureValidationFilter.java:158)
at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.filterMetadata(AbstractMetadataProvider.java:493)
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.processNonExpiredMetadata(AbstractReloadingMetadataProvider.java:395)

当我运行我的应用程序的主页时发生此异常

java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
at java.security.KeyStoreSpi.engineGetEntry(Unknown Source)
at java.security.KeyStore.getEntry(Unknown Source)
at org.opensaml.xml.security.credential.KeyStoreCredentialResolver.resolveFromSource(KeyStoreCredentialResolver.java:132)
4

7 回答 7

10

你的.cer证书只包含一个公钥,你不能<entry key="adfssigning" value="mypassword"/>为公钥定义;它只能用于私人的。只需取出该adfssigning条目并确保包含私钥 - 就像在 Spring SAML 示例应用程序中一样。

SAML 密钥库可以包含两种基本类型的密钥——公共密钥和私有密钥(加上它们的证书)。每个键都有一个别名,用于引用它。密钥库本身可以由密码保护(在第二个构造函数参数中提供),另外每个私钥也可以由一个额外的密码保护(这些在构造函数的第三个参数中定义在 alias->password 的映射中)。您导入到密钥库的公钥(就像您使用上面的命令一样)不得在此映射中定义。它们在导入后将自动可用,无需额外声明。要使 Spring SAML 工作,密钥库必须包含至少一个私钥(示例应用程序包含具有别名 apollo 的私钥),并且需要在构造函数的第三个参数中提供其别名。

您上面的示例失败,因为您已导入公钥,但将其包含在只能用于私钥的映射中。

于 2014-10-02T19:22:26.747 回答
10

Vladimir 正确回答了为什么会发生错误的问题。在我的回答中,我想展示如何将证书导入密钥库以解决该问题:

您必须导入keytool 无法直接完成的证书和私钥。

详细描述的解决方案可在此处找到:https ://stackoverflow.com/a/8224863/1909531

这是一段摘录:

openssl pkcs12 -export -in server.crt -inkey server.key \
           -out server.p12 -name [some-alias] \
           -CAfile ca.crt -caname root

keytool -importkeystore \
    -deststorepass [changeit] -destkeypass [changeit] -destkeystore server.keystore \
    -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass some-password \
    -alias [some-alias]
于 2016-03-17T13:55:17.277 回答
2

当您的密钥库中没有私钥时,也会发生此错误。SAML 使用私钥生成用于与 IDP 通信的服务提供者元数据。只需像这样向 Keystore 添加一个:

keytool -genkey -v -keystore some_key_store.jks -alias some_alias -keyalg RSA -keysize 2048 -validity 36500

填写问题并将有效期设置为适当的天数。(在我的示例中,有效期为 100 年)记得添加来自 IDP 的公共证书。那么你应该准备好了。

于 2018-05-24T06:43:56.943 回答
1

对于那些在 java config 中寻找答案的人,请注释掉 passwords.put("mykeyalias", "mystorepass"); ....显示在下面的代码片段中。

@Bean
public KeyManager keyManager() {
    DefaultResourceLoader loader = new DefaultResourceLoader();
    Resource storeFile = loader.getResource("classpath:saml-keystore.jks");
    Map<String, String> passwords = new HashMap<>();
    // passwords.put("mykeyalias", "mystorepass");
    return new JKSKeyManager(storeFile, "mystorepass", passwords, "mykeyalias");
}
于 2019-12-18T22:19:19.430 回答
0

使用 openssl 命令获取公共证书:

openssl s_client -showcerts -connect iam-sso.google.net:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem

将其导入密钥库:

keytool -import -alias "new-qet-alias" -keystore /usr/share/tomcat8/webapps/ROOT/WEB-INF/classes/saml/samlKeystore.jks -file mycertfile.pem
于 2019-06-13T10:08:57.687 回答
0

经过上述所有解决方案,如果问题仍然存在,可能值得检查您在使用密钥库中的证书时是否使用了正确的别名。在我的情况下,由于有多个证书条目,我输入了不正确的别名(实际上一个具有条目类型:trustedCertEntry 导致问题。而您应该使用一个具有条目类型:PrivateKeyEntry 的,只需检查现有证书使用

keytool -list -keystore "$JKS_CERT_PATH"  -storepass "$JKS_CERT_PASSPHRASE"  -noprompt -v
于 2021-09-30T04:08:12.053 回答
0

在尝试了一切,多次删除并重新创建 jks 文件后,没有任何效果。然后我碰巧滚动了这个页面,找到了 Pankaj 的答案,就是这样。我在属性文件中使用了错误的别名。正如 Pankaj 正确提到的,我们应该在属性文件中使用 PrivateKeyEntry 的别名,而不是trustedCertEntry。

然后步骤如下:

  1. 使用以下命令创建 JKS 文件。这也会将 PrivateKeyEntry 添加到 JKS 文件中。

    keytool -genkeypair -alias some_alias -keypass some_password -keyalg RSA -keysize 2048 -keystore samlKeystore.jks -validity 1825

  2. 将 IDP 证书导入其中。这会将trustedCertEntry 添加到文件中。

    keytool -importcert -alias some_other_alias -file file_name -keystore samlKeystore.jks

  3. 修改您的属性文件以使用您在创建 JKS 文件时提供的别名,即 PrivateKeyEntry 的别名

    sso.keystore.privatekey.alias=some_alias sso.keystore.default.certificate.alias=some_alias

  4. 重新启动您的服务器。

我一开始犯的另一个错误是我从 IDP 获得了 metadata.xml 文件,并且必须创建一个证书文件。我忘记在证书前后添加“-----BEGIN CERTIFICATE-----”和“-----END CERTIFICATE-----”,然后生成了无效的证书,让我很伤心. 证书应采用以下格式

-----BEGIN CERTIFICATE-----
BLAH-BLAH-BLAH-CERT
-----END CERTIFICATE-----
于 2022-02-23T01:33:21.063 回答