Ped*_*roD 1 java sockets ssl ssl-certificate tls1.2
我正在阅读有关在客户端和服务器之间创建安全连接的最佳方法。
通过本教程,看来证书(和密钥库)不仅被提供给服务器,而且还被提供给客户端。
这不安全吗?如果客户端具有证书文件(在密钥库中),它是否具有所有服务器私钥?
最后,我想要的是在客户端和服务器之间建立安全/加密的连接,而客户端本身向服务器证明它是真实的客户端。这是正确的方法吗?
谢谢!
正如鲍里斯(Boris)在第一条评论中所述,密钥库包含进行身份验证的密钥,信任库包含受信任的证书,正如其名称所暗示的那样。
首先,证书不必包含私钥。它只是带有公共密钥的身份(可能由受信任方(如CA)签名)。因此,如果使用得当,它并不是不安全的。合适的方法是什么?开始了:
在回答您的问题之前,即不仅对服务器进行身份验证而且对客户端进行身份验证的情况,让我们考虑通常的情况:仅服务器由客户端进行身份验证。在这种情况下,我们有三方:证书颁发机构(CA),服务器(S)和客户端(C)。要使其正常工作,您应该执行以下操作:
ca.jks。ca.jks并将其导入另一个jks文件,即truststore.jks。server.jks。server.jks,用来签名csr文件,ca.jks并生成一些包含签名证书的crt(或pem,无论您想要什么)文件。最后,您必须将此crt文件导入回server.jks。使用与以前相同的别名很重要。server.jks在S作为密钥库,并truststore.jks在C作为信任。ca.jks在安全的地方。这是信任的根源。这样,由于C的证书位于其信任库中,因此C信任CA。由于S具有CA签署的证书,因此C也将信任S。换句话说,S由C认证。
为了实现您想要的功能,即双方都经过了身份验证,您将拥有两个证书颁发机构,即CA1和CA2。(它们当然可以相同,但是为了完整起见,我这样写。)您必须做两次以上的过程:一次使用CA = CA1,一次使用CA = CA2。第一个与上面完全一样。在第二个示例中,您将创建client.jksCA2,并用CA2对其进行签名,并将CA2的公钥用作S的信任库。(只是交换C和S的角色。)这样,双方将相互进行身份验证。
如我所说,您可以使用相同的CA,这非常方便且合理。
我知道这是一个很长的答案,但是请确保我省略了大多数细节并试图使其简单。希望对您有所帮助。
编辑:同样,不要感到困惑:客户端使用存储在其密钥库中的私有密钥对自己进行身份验证。证书已经是公共事物了。
当然,如果您的窃贼窃取了密钥库文件,那么他可以模仿自己成为真正的客户。服务器无法知道与谁通信,他仅验证证书。对于这种情况,可以撤销已颁发的证书。在网络上搜索撤销。简而言之,如果您知道客户端的密钥库被盗,您将通过吊销通知服务器有关此事,而不是重新生成所有密钥材料。
一个极端的例子是,证书是某种公钥与身份的绑定。对于Web服务器,这是通常的情况,其证书将其公钥与主机名绑定在一起,即主机名是其身份。因此,如果abc.com使用为xyz.com颁发的证书,则当您尝试连接到abc.com时浏览器将显示错误消息。在Java世界中,这称为主机名验证。的common name证书字段用于此类身份。(当您使用openssl或密钥库生成时,它可能会问您一个通用名称,这非常重要。)如果您的客户端实际上是具有静态IP或某些有效域名的服务器,则可以使用它。这样,由于小偷将尝试从其他IP或域进行连接,因此服务器将通过主机名验证来检测到它。但是,通常客户没有这种稳定的身份,因此很难使用此技术,因此小偷可能能够模仿真实的客户。