SSO SAML的签名XML签名验证(使用sha256)

San*_*eep 8 .net c# saml sha256 signedxml

在Windows 2003服务器上使用VS 2008和.Net Framework 3.5.

为了安全起见,我们使用SAML实施了SSO.我们在服务提供商端工作,我们验证从客户端系统生成的签名XML SAML Assertuib令牌.截至目前,我们遇到的任何签名文档都使用了签名算法"rsa-sha1",但现在我们有新客户发送带有签名算法的文件"rsa-sha256",这就是问题的开始.

public static string VerifySignature()
{
    if (m_xmlDoc == null)
        return "Could not load XMLDocument ";

    try
    {
        XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
        nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl);
        XmlElement sigElt = (XmlElement)m_xmlDoc.SelectSingleNode(
            "//dsig:Signature", nsm);

        // Load the signature for verification
        SignedXml sig = new SignedXml(m_xmlDoc);
        sig.LoadXml(sigElt);

        if (!sig.CheckSignature())
            return "Invalid Signature";
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
    return string.Empty;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我为这个新客户尝试相同的代码(使用签名算法rsa-sha256h)时 - 这不起作用,我收到错误"无法为提供的签名算法创建SignatureDescription."

在过去2-3天内浏览了许多博客和文章,我发现SignedXml不支持sha256.精细.但接下来是什么.在其提到的某个地方使用WIF,我也检查过并试过这个.

我也在尝试使用RSAPKCS1SignatureDeformatter的VerifySignature方法.但不确定要传递的两个参数是什么.

O. *_*nes 9

Dotnet 4.6.2+内置了较新的sha哈希值.对于dotnet 4 +,要访问rsa-sha512,rsa-sha384和rsa-sha256,您应该在某处包含此代码.

/// <summary>Declare the signature type for rsa-sha512</summary>
public class RsaPkCs1Sha512SignatureDescription : SignatureDescription
{
    public RsaPkCs1Sha512SignatureDescription()
    {
        KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
        DigestAlgorithm = typeof(SHA512CryptoServiceProvider).FullName;
        FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
        DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    {
        var sigProcessor = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA512");
        return sigProcessor;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var sigProcessor =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA512");
        return sigProcessor;
    }
}

/// <summary>Declare the signature type for rsa-sha384</summary>
public class RsaPkCs1Sha384SignatureDescription : SignatureDescription {
    public RsaPkCs1Sha384SignatureDescription()
    {
        KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
        DigestAlgorithm = typeof(SHA384CryptoServiceProvider).FullName;
        FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
        DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    {
        var sigProcessor = (AsymmetricSignatureDeformatter) CryptoConfig.CreateFromName(DeformatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA384");
        return sigProcessor;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var sigProcessor =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA384");
        return sigProcessor;
    }
}

/// <summary>Declare the signature type for rsa-sha256</summary>
public class RsaPkCs1Sha256SignatureDescription : SignatureDescription
{
    public RsaPkCs1Sha256SignatureDescription()
    {
        KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
        DigestAlgorithm = typeof(SHA256CryptoServiceProvider).FullName;
        FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
        DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    {
        var sigProcessor =
            (AsymmetricSignatureDeformatter) CryptoConfig.CreateFromName(DeformatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA256");
        return sigProcessor;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var sigProcessor =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA256");
        return sigProcessor;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您应该通过调用这样的代码来激活这些sig描述.您只需要调用一次,因此如果您愿意,可以从静态构造函数中调用它.

    CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha512SignatureDescription),
        "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512");
    CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha384SignatureDescription),
        "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384");
    CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription),
        "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
Run Code Online (Sandbox Code Playgroud)

提示微软的Carlos LopezBitSchupster以及Andrew的SO.

  • ....和.....框架4.6.2处理这个问题而不需要额外的代码. (3认同)

mlh*_*Dev 2

这符合“简单”的条件,但可能不是“解决方案”:) 对于我们遇到过这种情况的少数客户,我们已要求他们更改其 IdP 以使用 SHA-1 进行签名。他们能够改变它,而且当他们这样做时,它就会起作用。

这不是一个技术解决方案,但它已经在“现场”发挥了作用,所以我想我应该提到它。