在X509Data节点中使用SKI代替证书的SAML

时间:2016-01-19 14:56:44

标签: x509certificate saml x509 saml-2.0

我已经实现了基于SAML协议的身份验证机制。项目使用SAML2 library。一切正常,直到服务器上的更改发生。用于响应节点的服务器:

<ds:KeyInfo><ds:X509Data><ds:X509Certificate>Here was certificate</ds:X509Certificate></ds:X509Data></ds:KeyInfo>

但它已改为:

<ds:X509SKI>Here is Subject Key Identifier</ds:X509SKI>

SAML2库具有CheckSignature方法,可以应用于服务器响应:

/// <summary>
/// Checks the signature.
/// </summary>
/// <returns>True of the signature is valid, else false.</returns>
public bool CheckSignature()
{
    return XmlSignatureUtils.CheckSignature(Document);
}

它指出:

/// <summary>
/// Verifies the signature of the XmlDocument instance using the key enclosed with the signature.
/// </summary>
/// <param name="doc">The doc.</param>
/// <returns><code>true</code> if the document's signature can be verified. <code>false</code> if the signature could
/// not be verified.</returns>
/// <exception cref="InvalidOperationException">if the XmlDocument instance does not contain a signed XML document.</exception>
public static bool CheckSignature(XmlDocument doc)
{
    CheckDocument(doc);
    var signedXml = RetrieveSignature(doc);

    if (signedXml.SignatureMethod.Contains("rsa-sha256"))
    {
        // SHA256 keys must be obtained from message manually
        var trustedCertificates = GetCertificates(doc);
        foreach (var cert in trustedCertificates)
        {
            if (signedXml.CheckSignature(cert.PublicKey.Key))
            {
                return true;
            }
        }

        return false;
    }

    return signedXml.CheckSignature();
}

最后,GetCertificates方法看起来像这样:

/// <summary>
/// Gets the certificates.
/// </summary>
/// <param name="doc">The document.</param>
/// <returns>List of <see cref="X509Certificate2"/>.</returns>
private static List<X509Certificate2> GetCertificates(XmlDocument doc)
{
    var certificates = new List<X509Certificate2>();
    var x509CertificateNodeList = doc.GetElementsByTagName("ds:X509Certificate");
    if (x509CertificateNodeList.Count == 0)
    {
        x509CertificateNodeList = doc.GetElementsByTagName("X509Certificate");
    }

    foreach (XmlNode xn in x509CertificateNodeList)
    {
        try
        {
            var xc = new X509Certificate2(Convert.FromBase64String(xn.InnerText));
            certificates.Add(xc);
        }
        catch
        {
            // Swallow the certificate parse error
        }
    }

    return certificates;
}

如您所见,库只检查不受主题密钥标识符限制的证书。我相信我可以在我自己的安装证书和提供的元素之间实现SKI比较,但我不确定这是否合法。

Here Thomas Pornin写道:

  

主题密钥标识符在验证中不起作用   至少不在构成RFC 5280第6节的算法中。它是   意在成为路径建设的帮助

他的声明建议我不能通过比较服务器响应和安装证书的SKI来进行验证。

RFC 5280建议相同,但我没有足够的时间仔细阅读,所以我正在寻找你的帮助。

是否正确比较了已安装的X509证书的主题密钥标识符和SAML响应中的主题密钥标识符以验证响应?

1 个答案:

答案 0 :(得分:1)

不,如前所述,SKI仅用于绑定链中的证书(使用密钥匹配时)。它没有提供有关证书及其详细信息的足够信息。

但是,如果客户端预装了完整的证书,客户端可以使用SKI找到正确的证书并使用证书进行验证。