【问题标题】:trusted certificate entries are not password-protected Spring SAML受信任的证书条目不受密码保护的 Spring SAML
【发布时间】:2014-11-27 15:16:04
【问题描述】:

我通过复制我计划连接的 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)

【问题讨论】:

标签: spring ssl spring-security x509 spring-saml


【解决方案1】:

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

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

你上面的例子失败了,因为你已经导入了一个公钥,但它包含在只能用于私钥的映射中。

【讨论】:

  • @vschafer 你的意思是说在spring SAML示例应用中映射到构造函数的参数2和3的nalle123对应的是同一个私钥?根据文档参数 2 对应于密钥库文件的密码。在 spring saml 示例应用程序中,我认为 keystore 文件的密码和私钥相同只是一个巧合。我怎样才能找回私钥?
  • @vschafer 你的意思是说在spring SAML示例应用中映射到构造函数的参数2和3的nalle123对应的是同一个私钥?根据文档参数 2 对应于密钥库文件的密码。在 spring saml 示例应用程序中,我认为 keystore 文件的密码和私钥相同只是一个巧合。如何创建 JKS?我目前只有添加到 .cer 文件中的公共证书,并且我正在使用命令 keytool -importcert -alias adfssigning -keystore samlKeystore.jks -file testIdp.cer
  • 我已经用额外的解释更新了答案。有关如何创建 JKS 和导入密钥的详细信息,请参阅 Spring SAML 手册或 Java 文档。
  • @vschafer 我参考了 Spring SAML 手册。但我仍然面临着私钥的问题。我已经使用手册中提到的命令创建了一个 JKS 文件,如下keytool -genkeypair -alias some-alias -keypass changeit -keystore samlKeystore.jks
  • 您面临什么样的问题 - 任何异常、错误 - 您在哪里发布的?
【解决方案2】:

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]

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      使用 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
      

      【讨论】:

        【解决方案5】:

        对于那些在 java config 中寻找答案的人,请注释掉该行 passwords.put("mykeyalias", "mystorepass"); .... 如下面的代码 sn-p 所示。

        @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");
        }
        

        【讨论】:

          【解决方案6】:

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

          检查现有证书
          keytool -list -keystore "$JKS_CERT_PATH"  -storepass "$JKS_CERT_PASSPHRASE"  -noprompt -v
          

          【讨论】:

            猜你喜欢
            • 2014-11-16
            • 2016-01-26
            • 2014-12-20
            • 2014-04-15
            • 2012-07-05
            • 2012-09-06
            • 2018-10-15
            • 2011-12-23
            相关资源
            最近更新 更多