Может ли использование самозаверяющих сертификатов с WCF быть безопасным? - PullRequest
4 голосов
/ 01 декабря 2010

Представьте на минуту, что мы используем классическую асимметричную запись с 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");
    }
}

1 Ответ

6 голосов
/ 01 декабря 2010

Да, ваше понимание верно, однако оно упускает одну вещь - все меняется со временем. Если секретный ключ сервера раскрывается или сертификат сервера становится недействительным иным образом (каким бы то ни было образом), PKI предлагает механизм отзыва и проверки отзыва. А с самозаверяющими сертификатами это невозможно (по крайней мере, без создания пользовательской инфраструктуры PKI).

Одним из способов решения этой проблемы является создание собственного самозаверяющего сертификата, который будет использоваться в качестве сертификата CA. Используйте этот сертификат, чтобы подписать сертификат сервера и поместить информацию об отзыве в сертификат CA. Затем добавьте сертификат CA как доверенный на стороне клиента и выполните проверку сертификата сервера по этому сертификату CA, а также проверьте аннулирование. Это означает, что вам придется либо опубликовать CRL на каком-то (возможно, частном) веб-сервере, либо запустить респондент OCSP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...