SSL和公钥安全
我正在使用带有SSL的HTTP(s)从Android设备使用Web服务。 自签名(不可信)证书用于客户端身份验证 。
我对公钥/私钥如何用于SSL有一个大体的了解。 根据我的理解,我可以清楚地看到如何使用证书来建立安全连接并安全传输数据。 但是,我不明白它们是如何用于客户端身份验证的,因为证书包含公钥并且不被保密。
我有几个问题:
我在哪里可以阅读如何使用SSL和证书进行客户端身份验证?
即使证书未公开...通过访问浏览器中的HTTPS URL,我可以查看并保存证书。 然后,我可以将证书打包在密钥存储区中并从应用程序中使用它。
Jeremy Huiskamp在这篇文章中写道
客户端身份验证将在服务器请求时自动执行
...所以客户端身份验证以及数据加密可以使用证书执行?
编辑回答我的问题的第一部分:客户端密钥库不仅应包含服务器的公钥,还应包含客户端的私钥 。 那么服务器必须能够使用客户端的公钥解密? 这是否意味着密钥库应该有两个证书?
首先,关于公钥加密术语的一个简短点:
(你并不真正使用公钥来“解密”。)
使用带/不带客户端身份验证的SSL / TLS,服务器会显示一个证书(*),该证书具有私钥。 服务器在SSL / TLS握手期间(在连接开始时)发送其证书,并能够解密客户端使用其私钥(私钥)发送的内容。 私钥和证书存储在服务器的密钥存储区中(如果未在Java中实现,则存储在该存储区中)。
作为其中的一部分,客户端使用其信任库(包含可信证书的密钥库的形式)来验证服务器证书。 服务器证书可以通过显式位于信任库中来信任,或者在大多数情况下通过链接到信任库(PKI)中的可信CA证书来信任。
Java中keystore和truststore之间的术语可能有点混乱,你可以在这个答案中找到更多的细节。
关于你的问题,客户的信任库不包含服务器的公钥,但是它的证书或者证书应该是可以验证的。 (这不仅仅是拥有公钥,而是知道它是谁,使用证书中的其他信息。)
除此之外,当您使用客户端证书身份验证时,服务器端还有一个信任库(或同等),客户端也有一个密钥库,因为角色为此目的被颠倒过来。
在使用客户端身份验证的SSL / TLS握手中,服务器从客户端请求证书,由其发送(如果可用)。
在握手结束时,客户端发送CertificateVerify
消息,该消息使用客户端证书私钥签署所有在客户端和服务器之间交换的消息(因此它们都是已知的)。 然后,服务器能够根据它作为此交换的一部分获得的客户端证书中的公钥验证此签名。 这向服务器证明,在客户端的任何人拥有与其发送的证书中的公钥相对应的私钥。
服务器的下一步是验证是否信任此证书,即是否信任证书中提供的和“密封”的身份和公钥之间的绑定。 这通常是使用PKI完成的,您可以根据已知的CA检查证书,或者如果您的部署环境足够小,则针对一组固定的可信证书进行检查。 (可以有其他的验证方法,但其可用性将取决于您想要部署此系统的情况。)
因此,对于你的第二个问题:
由于密钥库和信任库都是用于不同目的的密钥库(在存储格式意义上,通常是文件),因此通常可以使用相同的密钥库来实现密钥库和信任库的目的。
(*)有些密码套件不依赖证书,但对于这个问题来说,这是非常不寻常的问题。
证书只是将身份绑定到公钥上。 这种绑定不是秘密的,所以不需要保密证书。 如果我有约翰史密斯的证书,我可以证明约翰史密斯拥有与特定公钥对应的密钥。 但是因为我不知道那个秘密钥匙,所以证书对我来说没有用处。
当通过证书进行认证时,一个步骤总是让出示证书的人证明他们知道与证书中的公钥对应的秘密密钥。 如果您无法通过该步骤,则认证失败。
服务器的密钥库应该有服务器的证书。 客户的密钥库应该有客户的证书。 客户端会将其证书提供给服务器,这样服务器将以这种方式学习客户端的公钥。 (反之亦然)。
链接地址: http://www.djcxy.com/p/21759.html