如何根據 X509Certificate2Collection 鏈驗證 X509Certificate2
我正在編寫一個 SAML 2.0 響應解析器來處理 ASP.Net 中的 POST 身份驗證(在 C# 和 MVC 中,但這不太相關)。
所以我有一個
.p7b文件來驗證,它可以讀入X509Certificate2Collection一個範例斷言 - 一個 base 64 編碼的 SAML 響應。理想情況下,我想使用內置的
WSSecurityTokenSerializer,但是失敗了,所以我正在尋找一種可行的方法。我正在直接閱讀 XML:
// get the base 64 encoded SAML string samlAssertionRaw = GetFromHttpRequest(); // load a new XML document var assertion = new XmlDocument { PreserveWhitespace = true }; assertion.LoadXml(samlAssertionRaw); // use a namespace manager to avoid the worst of xpaths var ns = new XmlNamespaceManager(assertion.NameTable); ns.AddNamespace("samlp", @"urn:oasis:names:tc:SAML:2.0:protocol"); ns.AddNamespace("saml", @"urn:oasis:names:tc:SAML:2.0:assertion"); ns.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // get the signature XML node var signNode = assertion.SelectSingleNode( "/samlp:Response/saml:Assertion/ds:Signature", ns); // load the XML signature var signedXml = new SignedXml(assertion.DocumentElement); signedXml.LoadXml(signNode as XmlElement); // get the certificate, basically: // signedXml.KeyInfo.OfType<KeyInfoX509Data>().First(). // Certificates.OfType<X509Certificate2>().First() // but with added checks var certificate = GetFirstX509Certificate(signedXml); // check the key and signature match if (!signedXml.CheckSignature(certificate, true)) { throw new SecurityException("Signature check failed."); } // go on and read the SAML attributes from the XML doc這很有效,但它所做的只是檢查
X509Certificate2SAML 響應中的簽名和公鑰是否匹配。它不會以任何方式驗證它來自誰,我需要在接受 SAML 身份驗證之前這樣做。似乎有兩種方法可以檢查在 SAML 響應中找到的證書 - 我可以這樣做,
certificate.Verify()或者我可以使用簽名進行檢查signedXml.CheckSignature(certificate, false)。然而,兩者都返回假。
我認為這是因為他們正在根據機器商店或可能線上進行檢查(我不知道如何檢查)。我想對照
X509Certificate2Collection從文件中檢索到的內容來檢查它們.p7b——機器上註冊的證書應該被忽略,只.p7b檢查證書。似乎沒有任何方法可以將 傳遞
X509Certificate2Collection給VerifyorCheckSignature方法。這是對 SAML 響應進行的正確檢查嗎?
有什麼方法可以
.p7b按照我想要的方式使用證書嗎?
您是否嘗試過在驗證過程中使用自定義
X509Chain配置來搜尋證書。ExtraStore類似於以下內容:// Placeholder for the certificate to validate var targetCertificate = new X509Certificate2(); // Placeholder for the extra collection of certificates to be used var certificates = new X509Certificate2Collection(); var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.ExtraStore.AddRange(certificates); bool isValidCertificate = chain.Build(targetCertificate);在範例中,吊銷檢查也被禁用,但如果您對 CRL 具有線上或離線訪問權限,則可以啟用它。
ExtraStore應該允許包含不在機器/使用者儲存中的中間證書。但是,受信任的根證書可能需要位於機器或使用者儲存中,具體取決於 中指定的證書,X509Chain否則您將UntrustedRoot失敗。如果在機器或使用者儲存中連根都不可用,您可以嘗試沿著生成的鏈向上走,並保證您遇到的唯一錯誤是由於不受信任的根,同時保證鏈根是您的期望基於X509Certificate2Collection您的驗證。或者,您可以創建自己的自定義
X509CertificateValidator來驗證證書,僅考慮提供的X509Certificate2Collection.