簡體   English   中英

SSO SAML的簽名XML簽名驗證(使用sha256)

[英]Signed XML signature verification for SSO SAML (Using sha256)

在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;
}

現在,當我為這個新客戶嘗試相同的代碼(使用簽名算法rsa-sha256h)時 - 這不起作用,我收到錯誤“無法為提供的簽名算法創建SignatureDescription。”

在過去2-3天內瀏覽了許多博客和文章,我發現SignedXml不支持sha256。 精細。 但接下來是什么。 在其提到的某個地方使用WIF,我也檢查過並試過這個

我也在嘗試使用RSAPKCS1SignatureDeformatter的VerifySignature方法。 但不確定要傳遞的兩個參數是什么。

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;
    }
}

然后,您應該通過調用這樣的代碼來激活這些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");

提示微軟的Carlos LopezBitSchupster以及Andrew的SO。

對於.net 4及更早版本,我發現從http://clrsecurity.codeplex.com/添加Security.Cryptography后,以下工作正常。

(注意X509CertificateFinder是我自己的,通過指紋查找證書存儲區中的簽名證書)

        /// <summary>
        /// Validate an XmlDocuments signature
        /// </summary>
        /// <param name="xnlDoc"> The saml response with the signature elemenet to validate </param>
        /// <returns> True if signature can be validated with certificate </returns>
        public bool ValidateX509CertificateSignature(XmlDocument xnlDoc)
        {
            XmlNodeList XMLSignatures = xnlDoc.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#");

            // Checking If the Response or the Assertion has been signed once and only once.
            if (XMLSignatures.Count != 1) return false;

            var signedXmlDoc = new SignedXml(xnlDoc);
            signedXmlDoc.LoadXml((XmlElement)XMLSignatures[0]);

            var certFinder = new X509CertificateFinder();
            var foundCert = certFinder.GetSignatureCertificate();

            CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
            return signedXmlDoc.CheckSignature(foundCert,false);
        }

這符合“簡單”但可能不是“解決方案”的條件:)對於我們遇到過的少數客戶,我們已經要求他們使用SHA-1將他們的IdP更改為簽名。 他們能夠改變它,當他們這樣做時。

不是技術解決方案,但它在“現場”工作,所以我想我會提到它。

只需將其更新到.NET framework 4.6.01590或更高版本,它將支持SHA-512而無需更改任何代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM