【问题标题】:How to set Signature DigestMethod algorithm using OpenSAML如何使用 OpenSAML 设置 Signature DigestMethod 算法
【发布时间】:2014-07-23 05:17:17
【问题描述】:

我们可以设置签名算法如下:

signature.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

我正在尝试找到一种方法来设置这样的 DigestMethod 算法。是否可以通过 OpenSAML API 实现?非常感谢任何意见。

更新:为清楚起见添加示例签名。这个问题关心的是其中的 DigestMethod 元素。

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#_884D49DAD03AD60748547F8322C11AA0">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <ds:DigestValue>...</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>...</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:KeyName>...</ds:KeyName>
    </ds:KeyInfo>
  </ds:Signature>

更新:弗拉基米尔的回答有效。但是,该解决方案似乎是线程不安全的?在我的应用程序中,我们只引导 opensaml 一次,然后由具有不同配置的不同线程使用 - 例如不同的签名算法。有没有办法以线程安全的方式做到这一点?

更新: Shibboleth IdP 使用opensaml,根据Shibboleth IdP Wiki,目前这是一个全局配置。因此,无论 IdP 还是 SP 端,如果使用 opensaml 处理 SAML 消息,则应该存在此限制。以下是该文章的摘录:

更改 IdP 签名/摘要算法和相关设置是 目前是全球运营。算法将改变所有 与之交互的依赖方。在您完成之前不要进行此更改 已验证您的所有依赖方都可以使用 您选择的新算法

更新:终于找到了完成这项工作的方法。已将其添加为答案。

【问题讨论】:

  • 这不就是sha256到底是什么吗?
  • 据我了解签名算法和 DigestMethod 算法(在 Reference 元素内)是两个不同的东西。

标签: opensaml


【解决方案1】:

这可以通过在设置签名 [1] 后修改签名的内容引用来安全地完成线程。

例如

authnRequest.setSignature(signature);

((SAMLObjectContentReference)signature.getContentReferences().get(0))
           .setDigestAlgorithm(EncryptionConstants.ALGO_ID_DIGEST_SHA256);

[1]https://lists.internet2.edu/sympa/arc/mace-opensaml-users/2007-10/msg00003.html

【讨论】:

    【解决方案2】:

    在您的应用程序初始化期间尝试以下调用:

      BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
      config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
    

    【讨论】:

    • 谢谢!试过这个,它奏效了。但是,这似乎是一个全局配置,因此线程不安全。我对么?在我的应用程序中,我们只引导 opensaml 一次,然后由具有不同配置的不同线程使用 - 例如不同的签名算法。有没有办法以线程安全的方式做到这一点?感谢您的帮助。
    • 顺便说一句,SignatureConstants 没有 ALGO_ID_DIGEST_SHA256。它在 org.opensaml.xml.encryption.EncryptionConstants 中。
    【解决方案3】:

    查看 OpenSAML 源代码,另一种方法是扩展 DefaultBootstrap 和 DefaultSecurityConfigurationBootstrap 类,因此此配置可用于您的所有 SAML 实现。

    然后可以使用 CustomSamlBootstrap 类代替 DefaultSamlBootstrap 来初始化您的系统。

    例如:

    import org.opensaml.Configuration;
    import org.opensaml.DefaultBootstrap;
    import org.opensaml.xml.ConfigurationException;    
    public class CustomSamlBootstrap extends DefaultBootstrap {
        public static synchronized void bootstrap() throws ConfigurationException {
    
            initializeXMLSecurity();
    
            initializeXMLTooling();
    
            initializeArtifactBuilderFactories();
    
            initializeGlobalSecurityConfiguration();
    
            initializeParserPool();
    
            initializeESAPI();
    
            initializeHttpClient();
        }
    
        protected static void initializeGlobalSecurityConfiguration() {
            Configuration.setGlobalSecurityConfiguration(YourCustomSecurityConfigurationBootstrap.buildDefaultConfig());
        }
    
    }
    

    import org.opensaml.xml.security.BasicSecurityConfiguration;
    import org.opensaml.xml.security.DefaultSecurityConfigurationBootstrap;
    import org.opensaml.xml.signature.SignatureConstants;
    
    
    public class YourCustomSecurityConfigurationBootstrap extends DefaultSecurityConfigurationBootstrap {
        public static BasicSecurityConfiguration buildDefaultConfig() {
            BasicSecurityConfiguration config = new BasicSecurityConfiguration();
    
            populateSignatureParams(config);
            populateEncryptionParams(config);
            populateKeyInfoCredentialResolverParams(config);
            populateKeyInfoGeneratorManager(config);
            populateKeyParams(config);
    
            return config;
        }
    
        /**
         * Populate signature-related parameters.
         *
         * @param config the security configuration to populate
         */
        protected static void populateSignatureParams(BasicSecurityConfiguration config) {
            // Asymmetric key algorithms
            config.registerSignatureAlgorithmURI("RSA", SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
            config.registerSignatureAlgorithmURI("DSA", SignatureConstants.ALGO_ID_SIGNATURE_DSA);
            config.registerSignatureAlgorithmURI("EC", SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA1);
    
            // HMAC algorithms
            config.registerSignatureAlgorithmURI("AES", SignatureConstants.ALGO_ID_MAC_HMAC_SHA1);
            config.registerSignatureAlgorithmURI("DESede", SignatureConstants.ALGO_ID_MAC_HMAC_SHA1);
    
            // Other signature-related params
            config.setSignatureCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
            config.setSignatureHMACOutputLength(null);
            config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA1);
        }
    
    }
    

    编辑:看到您想为不同的线程使用不同的安全配置。

    为此,您可能希望扩展 BaseSAML2MessageEncoder 的最合适的子类以覆盖 signMessage 函数。然后根据需要将 YourCustomSecurityConfigurationBootstrap 传递给 SecurityHelper.prepareSignatureParams(Signature signature, Credential signingCredential, SecurityConfiguration config, String keyInfoGenName) 方法。

    【讨论】:

      【解决方案4】:

      我这样做的方式是创建自己的类 TenantAwareSecurityConfiguration 实现 SecurityConfiguration 接口。它有一个属性委托,最终分配给 BasicSecurityConfiguration 的默认实现。

      我在一个单独的 bean 中执行此操作,该 bean 在初始实例化已经发生后被调用。在这个 bean 中,我初始化了自己的类,并在构造函数中传递了默认的 BasicSecurityConfiguration 实例。

      现在在我的课堂上,我重写了获取摘要和签名算法的 2 种方法。对于其余的方法,我只是将调用委托给底层委托。

      这样您就可以拥有自己的这些方法的实现。就我而言,我需要获取特定于租户的算法,因此这些方法会从租户属性中返回特定于租户的算法。

      将很快发布代码sn-ps。

      【讨论】:

        猜你喜欢
        • 2013-09-23
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 2012-04-25
        • 1970-01-01
        • 2019-10-30
        相关资源
        最近更新 更多