X509Certificate2.Verify () в этом случае будет возвращать true, пока сертификат не выдан серверу, на котором он установлен.
Метод Verify
не проверяет что-нибудь о именах хостов. Он проверяет, что
- Срок действия сертификата не истек.
- Сертификат в конечном итоге связывается с доверенным root полномочием.
- Все сертификаты в цепочке соответствующим образом вложены expiration.
- Целевой сертификат, если он не выдан самостоятельно, имеет конечную точку отзыва и не отозван.
- Любые промежуточные сертификаты имеют конечные точки отзыва и не отозваны.
Это точно равно
using (X509Chain chain = new X509Chain())
{
// Use the default vales of chain.ChainPolicy including:
// RevocationMode = X509RevocationMode.Online
// RevocationFlag = X509RevocationFlag.ExcludeRoot
// VerificationFlags = X509VerificationFlags.NoFlag
// VerificationTime = DateTime.Now
// UrlRetrievalTimeout = new TimeSpan(0, 0, 0)
bool verified = chain.Build(cert);
for (int i = 0; i < chain.ChainElements.Count; i++)
{
chain.ChainElements[i].Certificate.Dispose();
}
return verified;
}
Есть ли готовый блок кода для полной проверки сертификата X509?
Если "полная проверка" просто означает все то, что делает Verify
, тогда да. Если вы также заботитесь о том, чтобы он действовал в качестве сертификата клиента TLS (или сертификата сервера TLS), вы должны использовать более длинную форму (с использованием X509Chain напрямую) и добавить требование политики приложения перед вызовом chain.Build:
// See if it's valid as a TLS server
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1"));
// Alternatively, if it's valid as a TLS client
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.2"));
Имя хоста намного сложнее. Клиентские сертификаты не имеют проверяемых имен, это зависит только от того, что сервер делает с ним. Сертификаты сервера имеют сопоставление имени хоста с SAN / Subject-CN, но нет ничего встроенного, что делает такую проверку, кроме простого соединения с TLS (SslStream
).