Представьте на минуту, что мы используем классическую асимметричную запись с WCF (пары секретного / открытого ключа).Очевидно, это безопасно, пока закрытые ключи не будут украдены.Нам не нужны цепочки доверия между ключами, верно?Клиенту нужно знать только открытый ключ своего сервера и наоборот.
Проблема возникает, только если клиент заранее не знает открытый ключ сервера и получает его при первом доступе.Здесь мы рискуем, чтобы реальный сервер был «человеком посередине», а не реальным сервером.Здесь нам нужны сертификаты.Клиент получает доступ к серверу, получает свой сертификат (который содержит открытый ключ) и проверяет его.
Для проверки клиент должен убедиться, что сертификат сервера был выдан для этого конкретного сервера.И здесь нам нужны цепочки доверия.Правильно?
Если клиент, обращающийся к серверу через WCF с помощью MessageSecurity.Mode = Certificate, заранее знает сертификат сервера (его открытый ключ), можем ли мы сказать, что связь безопасна, даже если сертификат самоподписан?
Обычно считается, что использование самозаверяющего сертификата небезопасно и его всегда следует избегать при производстве.
Но почему?Если клиент знает ожидаемый открытый ключ, затем получает сертификат, обрабатывает его как доверенный (сопоставляя свой открытый ключ с ожидаемым), тогда он не отменяет тот факт, что сервер должен зашифровать полезную нагрузку своим закрытым ключом.И шифр может быть успешно расшифрован с помощью пульсирующего ключа, если и только если закрытый ключ и открытый ключ были созданы вместе.
Можете ли вы увидеть какие-либо недостатки в моих рассуждениях?
Если это правильно, то могу ли я быть уверен, что с помощью пользовательского X509CertifacateValidator и установкой ClientCredentials.ServiceCertificate.DefaultCertificate клиентского прокси-сервера некоторые исправлены (на клиенте) X509Сертификат безопасности?
Пользовательский X509CertifacateValidator выглядит примерно так:
public class CustomCertificateValidator : X509CertificateValidator
{
private readonly X509Certificate2 m_expectedCertificate;
public CustomCertificateValidatorBase(X509Certificate2 expectedCertificate)
{
m_expectedCertificate = expectedCertificate;
}
public override void Validate(X509Certificate2 certificate)
{
ArgumentValidator.EnsureArgumentNotNull(certificate, "certificate");
if (certificate.Thumbprint != m_expectedCertificate.Thumbprint)
throw new SecurityTokenValidationException("Certificated was not issued by trusted issuer");
}
}