12

我在获取 Spring SAML 集成以为我的 IdP 生成正确的元数据文件时遇到问题。我获得了新的 SHA256 SSL 证书。我已经完成了所有步骤来创建适当的 keyStore 并设置了我的 Spring 安全配置文件。从字面上看,我已经完成了 98% 的工作,但是生成的元数据文件中缺少一件事,我终其一生都无法弄清楚为什么它没有被设置。

这是 MetadataGeneratorFilter 的 ExtendedMetadata 配置:

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
    <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
        <property name="entityId" value="urn:myentityidhere"/>
        <property name="entityBaseURL" value="https://${saml.url}"/>
        <property name="extendedMetadata">
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                <property name="signMetadata" value="true"/>
                <property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <property name="alias" value="ceo"/>
                <property name="signingKey" value="${saml.sp.alias}"/>
                <property name="encryptionKey" value="${saml.sp.alias}"/>
            </bean>
        </property>
    </bean>
</constructor-arg>

当我运行我的应用程序并转到 /saml/metadata URI 以让 Spring 生成我需要发送到我的 IdP 的元数据文件时,SHA256 算法在 SignatureMethod 上得到正确设置,但子 DigestMethod 标记的算法值仍然设置到 SHA1,当我需要将 ALSO 设置为 SHA256 以及 DigestValue 为 SHA256 值而不是 SHA1 值时。

<ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <ds:Reference URI="#urn_myentityidhere">
        <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>xxxxxxx</ds:DigestValue>
    </ds:Reference>
</ds:SignedInfo>

有人可以指导我如何/我需要设置什么才能将 DigestMethod 算法值也设置为 256?我想,因为它是 SignedInfo 标记的子项,它会从 Extendedmetadata 配置继承 signingAlgorithm 值,但可惜不是。

任何帮助将不胜感激。非常感谢。

解决方案 - 如果有人关心

所以,经过一天的挖掘,我决定自己实现这个。我通过添加字段 digestMethodAlgorithm 扩展了 ExtendedMetadata 类,并添加了适当的 getter/setter:

/**
 * Algorithm used for creation of digest method of this entity. At the moment only used for metadata signatures.
 * Only valid for local entities.
 */
private String digestMethodAlgorithm;

/**
 * Returns digest method algorithm value
 * @return String
 */
public String getDigestMethodAlgorithm()
{
    return digestMethodAlgorithm;
}

/**
 * Sets the digest method algorithm to use when signing the SAML messages.
 * This can be used, for example, when a strong algorithm is required (e.g. SHA 256 instead of SHA 128).
 * If this property is null, then the {@link org.opensaml.xml.Configuration} default algorithm will be used instead.
 *
 * Value only applies to local entities.
 *
 * At the moment the value is only used for signatures on metadata.
 *
 * Typical values are:
 * http://www.w3.org/2001/04/xmlenc#sha1
 * http://www.w3.org/2001/04/xmlenc#sha256
 * http://www.w3.org/2001/04/xmlenc#sha384
 * http://www.w3.org/2001/04/xmlenc#sha512
 * http://www.w3.org/2001/04/xmlenc#ripemd160
 *
 * @param digestMethodAlgorithm The new digest method algorithm to use
 * @see org.opensaml.xml.signature.SignatureConstants
 */
public void setDigestMethodAlgorithm(String digestMethodAlgorithm)
{
    this.digestMethodAlgorithm = digestMethodAlgorithm;
}

然后我从上面修改了我的 spring 安全配置,将这个新的 bean 属性包含在我的 MetadataGenerator 配置中:

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
    <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
        <property name="entityId" value="urn:myentityidhere"/>
        <property name="entityBaseURL" value="https://${saml.url}"/>
        <property name="extendedMetadata">
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                <property name="signMetadata" value="true"/>
                <property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <property name="digestMethodAlgorithm" value="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <property name="alias" value="ceo"/>
                <property name="signingKey" value="${saml.sp.alias}"/>
                <property name="encryptionKey" value="${saml.sp.alias}"/>
            </bean>
        </property>
    </bean>
</constructor-arg>

然后我还必须对 SAMLUtil 类进行两次更改。在 getmetadataAsString 中,在 isSignMetadata() if 子句中,我提取了上面配置设置的 digestMethodAlgorithm 的注入值,然后进一步修改了 marshallAndSignMessage 方法以接受一个新的输入参数,我进一步使用它来正确设置 DigestMethod 算法.

在 SAMLUtil.getMetaDataAsString 内部,第 572 行

...
String digestMethodAlgorithm = extendedMetadata.getDigestMethodAlgorithm();
element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, digestMethodAlgorithm, keyGenerator);
...

在 SAMLUtil.marshallAndSignMessage 内部,就在第 437 行之后,我添加/更改了以下内容:

...
BasicSecurityConfiguration secConfig = null;

if (digestMethodAlgorithm != null)
{
    secConfig = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();

    secConfig.setSignatureReferenceDigestMethod(digestMethodAlgorithm);
}

try {
    SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, keyInfoGenerator);
} catch (org.opensaml.xml.security.SecurityException e) {
    throw new MessageEncodingException("Error preparing signature for signing", e);
}
...

我通过 Gradle 重新编译了整个 Spring SAML 核心包 spring-security-saml-1.0.0.RELEASE,将新 jar 从 build/libs 目录复制到我的项目,部署了 webapp,将我的浏览器指向 /saml/metadata 和成功获得了元数据文件中正确的 SHA256 签名部分的元数据文件。

我将看看我能做些什么来将它提交给这个项目的 git 存储库,因为我不想失去这个能力,因为这个项目会在未来的版本中发布。以前从未为这样的开源项目做出过贡献。

<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
    <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/2001/04/xmlenc#sha256"/>
    <ds:DigestValue>xxxxxx</ds:DigestValue>
</ds:Reference>

4

3 回答 3

13

自从@VladimírSchäfer 回答以来,情况似乎发生了变化;它不适用于我们使用 AD FS 2.0 和 SHA-256。我们必须添加一个额外的设置才能让它工作(见下面的代码)。

问题似乎出在 OpenSAML 的 xmltooling 库中,特别是org.opensaml.xml.security.BasicSecurityConfiguration.getSignatureAlgorithmURI(Credential)方法 - 而不是仅使用证书的签名算法(在我们的例子中,SHA256withRSA),它获取证书的密钥,然后查看该密钥的算法并使用已注册 URI 的映射以查找签名 URI。如果他们只有 JCA签名算法到 URI 的映射,而不是 URI 的密钥算法,那一切都很好。

解决方法是在 Spring 连接期间注册正确的签名算法 URI BasicSecurityConfiguration,覆盖http://www.w3.org/2000/09/xmldsig#rsa-sha1已经存在的(不受欢迎的)URI http://www.w3.org/2001/04/xmldsig-more#rsa-sha256

我们还必须删除调用,否则将setSignatureReferenceDigestMethod()元数据导入 AD FS 会失败。

import org.opensaml.Configuration;
import org.opensaml.xml.security.BasicSecurityConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.security.saml.SAMLBootstrap;

public class CustomSamlBootstrap extends SAMLBootstrap {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
super.postProcessBeanFactory(beanFactory); BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration(); config.registerSignatureAlgorithmURI("RSA", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); } }
于 2015-10-08T18:38:46.087 回答
10

您可以通过在 Spring SAML 初始化期间进行以下调用来配置用于计算数字签名的摘要方法:

// Use SHA-256 signatures for RSA keys
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);

例如扩展默认值org.springframework.security.saml.SAMLBootstrap并在调用 super 后将代码添加到覆盖的 postProcessBeanFactory 方法:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    super.postProcessBeanFactory(beanFactory);
    BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
    config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
}

此更改会影响生成的元数据中的签名和生成的 SAML 消息中的签名。

于 2014-09-23T20:26:24.220 回答
0

在 SAMLBootstrap 中对全局安全配置进行更改后,我遇到了以下异常:

org.apache.xml.security.signature.XMLSignatureException:请求的算法 SHA256withRSA 不存在。原始消息是: SHA256withRSA MessageDigest 在 org.apache.xml.security.algorithms.MessageDigestAlgorithm.getInstance(Unknown Source) 在 org.apache.xml.MessageDigestAlgorithm.getDigestInstance(Unknown Source) at org.apache.xml 不可用.security.signature.Reference.(Unknown Source) at org.apache.xml.security.signature.Manifest.addDocument(Unknown Source) at org.apache.xml.security.signature.XMLSignature.addDocument(Unknown Source)

经过进一步调查发现,Apache XML Securityxmlsec-1.4.3.jar不支持底层SHA256withRSA算法。

分辨率:使用xmlsec-2.0.2.jar来自https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.0.2

这个新罐子解决了这个问题。

于 2017-07-14T22:58:21.607 回答