Can using self-signed certificates with WCF be sec

2019-06-28 04:18发布

问题:

Imagine for a moment that we're using classic asymmetric encription with WCF (private/public key pairs). Obviously it's secure until private keys aren't stolen. We don't need any trust chains between keys, right? Client only needs to know its server's public key and vice versa.

A problem arises only if client doesn't know server's public key in advance and gets it on the first access. Here we have a risk that actual server is a "man-in-the-middle" instead of the real server. Here we need certificates. Client accesses a server, gets its certificate (which contains public key) and validates it.

For validation client needs to make sure that server's certificate was issued for this particular server. And here we need trust chains. Right?

If a client accessing a server via WCF with MessageSecurity.Mode=Certificate knowns in advance the server's certificate (its public key), can we say that the communication is secure even if the certificate is self-signed?

Usualy it's believed that using self-signed certifacate is not secure and should be always avoided in production.
But why? If client knows expected public key then gets a certificate, treats it as trusted (by matching its public key with the expected one) then it doesn't cancel the fact that the server must encypt payload with its private key. And the cypher can be decrypted successfuly with pulbic key if and only if the private key and the public key were created together.

Can you see any flaws in my reasoning?

If it's correct then can I be sure that using a custom X509CertifacateValidator and setting client proxy's ClientCredentials.ServiceCertificate.DefaultCertificate to some fixed (on the client) X509Certificate secure?

Custom X509CertifacateValidator is something like this:

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:

Yes, your understanding is correct, however it misses one thing - things change over time. If server's private key is disclosed or server's certificate becomes invalid in other way (whatever), PKI offers the mechanism for certificate revocation and revocation checking. And with self-signed certificates this is not possible (at least without building custom PKI infrastructure).

One way to address this problem is to create a custom self-signed certificate which will be used as a CA certificate. Use this certificate to sign the server certificate and put revocation information into the CA certificate. Then add the CA certificate as trusted on the client side, and perform validation of server's certificate against this CA certificate and also check revocation. This means that you will have to either publish CRLs on some (possibly private) web server, or run the OCSP responder.