Как проверить X509Certificate2 по цепочке X509Certificate2Collection - PullRequest
10 голосов
/ 25 мая 2011

Я пишу анализатор ответов SAML 2.0 для обработки аутентификации POST в ASP.Net (в C # и MVC, но это менее актуально).

Итак, у меня есть файл .p7b для проверки икоторый может быть прочитан в X509Certificate2Collection и пример утверждения - ответ SAML в кодировке Base 64.

В идеале я хочу использовать встроенный 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

Эта партия работает, но все, что она делает, это проверяет, что подпись и X509Certificate2 открытый ключ в ответе SAML.Он никоим образом не проверяет, от кого он, и мне нужно сделать это до принятия аутентификации SAML.

Похоже, есть два способа проверить сертификат, найденный в ответе SAML - я могу сделать certificate.Verify() или я могу выполнить проверку с подписью signedXml.CheckSignature(certificate, false).

Однако оба возвращают false.

Я думаю, это потому, что они проверяются в магазине оборудования или, возможно, онлайн (Я не уверен, как проверить).Вместо этого я хочу сравнить их с X509Certificate2Collection, полученным из файла .p7b - сертификаты, зарегистрированные на аппарате, следует игнорировать, а проверять только .p7b сертификаты.

Похоже, что нетлюбой способ передать X509Certificate2Collection в методы Verify или CheckSignature.

Правильно ли выполнять проверку ответа SAML?

Есть ли способиспользовать .p7b сертификаты так, как я хочу?

1 Ответ

5 голосов
/ 31 мая 2011

Вы пытались использовать пользовательский 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.

...