我正在尝试在将暴露给公共(public)互联网的服务器上设置 TCP 流(非 HTTP),但只有“选择的”客户端应该能够连接到。据我了解,这通常由证书固定处理,但我不熟悉如何完成的所有细节。
private SslStream GetSslStream(TcpClient client, string certificateFile)
{
var c = X509Certificate.CreateFromCertFile(certificateFile);
var cert = new X509Certificate2(c);
if (!cert.Verify()) {
throw new Exception("Certificate failed verification");
}
var stream = new SslStream(client.GetStream(), false, VerifyClientCert);
stream.AuthenticateAsServer(cert, true, true);
return stream;
}
VerifyClientCert
中的内容确保它是正确的证书的方法?只需 Verify()
并检查 Thumbprint
与预期值相反,还是需要发生更多事情? 最佳答案
证书固定是一个不同的概念。服务器使用 SSL 证书时,通常是由某个证书颁发机构颁发的。该机构的证书又可以由另一个证书机构颁发,形成一个链。当客户端验证服务器证书时,它会检查该证书颁发机构是否被此特定客户端“信任”。 “受信任”反过来意味着上述链中的某些证书受此客户端信任。例如,Windows 和 Linux 操作系统都带有一组默认受信任的证书权限。如果服务器证书在其链中具有其中一些权限 - 那么它也是受信任的。
证书固定意味着您作为客户端对服务器证书施加的限制比上述限制更多。例如,你可能会说对于这个域\端点,我只信任这个特定的证书(带有这个特定的摘要),我根本不关心信任链。或者对于这个端点,我只信任这个特定的证书颁发机构。这是证书固定。您可以将它用于您的服务器,但它有它的缺点,我不会在这里描述。
现在回到你的问题。您所描述的称为客户端证书身份验证。在 SSL 握手中,不仅服务器可以提供证书供客户端验证。服务器也可能要求客户端发送他自己的证书,以验证该客户端。这个证书当然与服务器的证书完全不同。
每个客户都必须有不同证书。通常使用以下两个选项之一:
关于c# - 如何为 TcpClient 实现证书固定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69598046/