想象一下,我们正在使用WCF(私钥/公钥对)的经典非对称编码。显然,在私钥没有被盗之前它是安全的。我们在密钥之间不需要任何信任链,对吧?客户端只需知道其服务器的公钥,反之亦然。
只有当客户端事先不知道服务器的公钥并在第一次访问时获取它时,才会出现问题。在这里,我们冒着实际服务器是“中间人”而不是真实服务器的风险。我们需要证书。客户端访问服务器,获取其证书(包含公钥)并验证。
对于验证客户端需要确保为此特定服务器颁发了服务器证书。在这里,我们需要信任链。对?
如果通过WCF使用MessageSecurity.Mode = Certificate访问服务器的客户端事先知道服务器的证书(其公钥),即使证书是自签名的,我们是否可以说通信是安全的?
通常认为使用自签名证书并不安全,应始终在生产中避免使用。
但为什么?如果客户端知道预期的公钥然后获取证书,则将其视为可信(通过将其公钥与预期的公钥匹配),然后它不会取消服务器必须使用其私钥加密有效负载的事实。当且仅当私钥和公钥一起创建时,才能使用pulbic密钥成功解密密码。
你能看出我推理中的任何缺陷吗?
如果它是正确的,那么我可以确定使用自定义X509CertifacateValidator并将客户端代理的ClientCredentials.ServiceCertificate.DefaultCertificate设置为某些固定的(在客户端上)X509Certificate安全吗?
自定义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");
}
}
答案 0 :(得分:6)
是的,你的理解是正确的,但它错过了一件事 - 事情会随着时间而改变。如果披露服务器的私钥或服务器的证书以其他方式变为无效(无论如何),PKI提供证书撤销和撤销检查的机制。使用自签名证书这是不可能的(至少在没有构建自定义PKI基础结构的情况下)。
解决此问题的一种方法是创建一个自定义自签名证书,该证书将用作CA证书。使用此证书对服务器证书进行签名,并将吊销信息放入CA证书中。然后在客户端将CA证书添加为受信任的证书,并根据此CA证书执行服务器证书的验证,并检查吊销。这意味着您必须在某些(可能是私有的)Web服务器上发布CRL,或运行OCSP响应程序。