Imagine that we are using a classic asymmetric subscription with WCF (private / public key pairs). Obviously, this is safe until private keys are stolen. We don't need trust chains between keys, right? The client should know only its public key of the server and vice versa.
The problem arises only if the client does not know the server’s public key in advance and receives it upon first access. Here we risk that the actual server is a “man in the middle” and not a real server. Here we need certificates. The client accesses the server, receives its certificate (which contains the public key) and verifies it.
For verification, the client needs to make sure that the server certificate has been issued for this particular server. And here we need chains of trust. Right?
If a client accessing the server through WCF with MessageSecurity.Mode = Certificate knows the server certificate (its public key) in advance, can we say that the connection is secure even if the certificate is self-signed?
He usually believed that using self-signed certifacate was unsafe and should always be avoided in production.
But why? If the client knows that the expected public key then receives the certificate, it perceives it as trusted (by matching its public key with the expected one), then it does not negate the fact that the server must encode the payload with its private key. And the cipher can be successfully decrypted using a button key, if and only if the private key and public key were created together.
Do you see any flaws in my reasoning?
If this is correct, can I be sure that using the custom X509CertifacateValidator and setting the ClientCredentials.ServiceCertificate.DefaultCertificate client proxy to any fixed (on the client) X509Certificate certificate is safe?
The custom X509CertifacateValidator looks 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"); } }
source share