客户端证书认证

Client certificate authentication

我不熟悉 SSL 和证书。我一直在研究客户端证书身份验证。我已阅读 this and wiki

因此,如果我必须为我的 B2B REST 服务实施客户端证书身份验证解决方案,我应该执行以下操作

  1. 要求客户生成他们自己的私有 public 密钥并为其 public 密钥生成证书(CA 颁发?)。通过电子邮件或 USB 密钥发送该证书。
  2. 在服务器端将客户端的 public 证书导入信任库并启用客户端身份验证
  3. 在握手过程中,客户端出示它的证书并通过身份验证,因为服务器在其信任库中有一份证书副本,可以验证 CertificateVerify 消息

我的问题是它如何阻止任何人冒充我的客户。假设黑客 X 作为握手的一部分向服务器发送了经过认证的 CA。然后服务器会自动信任它并授予访问权限。

我要把你的问题分成两部分。

第一部分:Let's say a hacker X sends a CA issued certified to the server as part of handshake. Then server would automatically trust it and grant access.

如果X获取的是真实客户端的客户端证书,那没问题。因为证书本身不包含任何秘密。这些证书可以在任何地方发布而不会造成任何损害 (除非你想对你的电子邮件地址保密,尽量不要发布它。但它可能会在一段时间后泄露出去。公司制作的 X509CertificateExtensions 是也不考虑。).

私钥是您的客户端必须保密的重要密钥。如果 X 也获得了私钥,X 就可以强加一个真实的客户端并登录到您的系统。因此客户必须保护这些私钥不被盗!

那是因为在client-auth握手中,服务器不仅请求客户端证书。客户还必须使用 the wiki you referenced 中所述的私钥证明他是证书的真正所有者: The client sends a CertificateVerify message, which is a signature over the previous handshake messages using the client's certificate's private key. 这样的签名只能 完成如果客户端拥有属于证书的私钥,如 wiki 中所述:This lets the server know that the client has access to the private key of the certificate and thus owns the certificate.!

第二部分:How do establish a initial trust relationship?

如果涉及的客户很多,那部分就比较难了。这就是 PKI 成立的原因。您信任CA,CA应该对请求证书的客户端进行身份检查。

对于自制解决方案,在这种情况下,您拥有自己的 CA,或者您不信任 CA,这部分由您决定。 您必须确保只有真实的客户才能访问您的服务。如果你用U盘做,客户亲自交给你,那没问题。

如果您收到一封电子邮件 "hello, i'm your friend XYZ from ABC, remember? Btw. here's my certificate" - 请检查两次。

基于客户端证书的身份验证实际上不会验证客户端连接是否在您的白名单中。

假设客户端 X 从 public CA Y 获得证书,并且您将 Y 的证书导入到您的信任列表中,那么来自 X 的连接就会成功。

现在,如果入侵者 Z 从同一个 CA Y 购买证书(知道您的应用程序信任哪个 CA 是一个复杂的部分),并尝试对您的应用程序进行身份验证,验证仍然会成功,因为它是有效的来自受信任的 CA 的证书。该应用程序将继续向 Z 提供您不想要的内容。

所以最好的方法是自行签署客户端证书(并将其部署在您信任的客户端上),在这种情况下您将成为 CA,这会限制入侵者获得访问权限。

这里有一些参考,

# Create the CA Key and Certificate for signing Client Certs
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

# Create the Client Key and CSR
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr

# Sign the client certificate with our CA cert.
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

如果您只想允许几个已知的 IP 地址,那么基于网络的 IP blocking/Throttling 是首选方法(但是,managing/updating IP 列表有其自身的复杂性)。