Я борюсь с некоторыми X509-сертификатами для звонков на веб-сервис HTTPS. Там, где я создаю это, корневому центру сертификации не доверяют, но он действителен лично для меня, для какой программы я работаю. Поэтому я пытался использовать ServerCertificateValidationCallback
в C #, чтобы это работало, как было найдено в другом вопросе stackoverflow.
Мне интересно, есть ли способ добавить несколько X509VerificationFlags для прохождения сертификата. Я просто нервничаю, отвергая реализацию .NET.
Boolean ServerCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
X509Certificate2 UATrootCA = new X509Certificate2("MyInvalidRootCAButIWantToTrustItAnyway.cer");
// remove this line if commercial CAs are not allowed to issue certificate for your service.
if ((sslPolicyErrors & (SslPolicyErrors.None)) > 0) { return true; }
if (
(sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNameMismatch)) > 0 ||
(sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNotAvailable)) > 0
) { return false; }
// get last chain element that should contain root CA certificate
//X509Certificate2 projectedRootCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
//if (projectedRootCert.Thumbprint == UATrootCA.Thumbprint)
//{
// return true; // I could return true here if I really wanted to and it would work fine, but I feel like there might be a better way...
//}
// execute certificate chaining engine and ignore only "UntrustedRoot" error
X509Chain customChain = new X509Chain
{
ChainPolicy = {
VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority
}
};
customChain.ChainPolicy.ExtraStore.Add(UATrootCA);
Boolean retValue = customChain.Build(chain.ChainElements[0].Certificate);
// RELEASE unmanaged resources behind X509Chain class.
customChain.Reset();
return retValue;
}
ОБНОВЛЕНИЕ 1
Спасибо за комментарий bartonjs
. Из-за этого комментария я чувствовал себя глупо. Иногда отладка по признанию является лучшим способом. В итоге я получил немного другой код, который все еще проверял отпечаток.
Boolean ServerCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
X509Certificate2 UATrootCA = new X509Certificate2("MyInvalidRootCAButIWantToTrustItAnyway.cer");
if (
(sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNameMismatch)) > 0 ||
(sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNotAvailable)) > 0
) { return false; }
// get last chain element that should contain root CA certificate
// but this may not be the case in partial chains
X509Certificate2 projectedRootCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
X509Chain customChain = new X509Chain();
Boolean retValue = false;
// execute certificate chaining engine and ignore only "UntrustedRoot" error if our Thumbprint matches.
if (projectedRootCert.Thumbprint == UATrootCA.Thumbprint)
{
customChain = new X509Chain
{
ChainPolicy = { VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority }
//ChainPolicy = { VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority |
// X509VerificationFlags.IgnoreRootRevocationUnknown }
// As bartonjs commented you can use a bitwise-or to add different VerificationFlags which can be very useful
};
retValue = customChain.Build(UATrootCA);
}
else
{
retValue = customChain.Build(chain.ChainElements[0].Certificate);
}
// RELEASE unmanaged resources behind X509Chain class.
customChain.Reset();
return retValue;
}