SSL和公钥安全性

Jac*_*ack 6 ssl ssl-certificate

我正在使用带有SSL的HTTP从Android设备上使用Web服务.自签名(不受信任)证书用于客户端身份验证.

我对如何使用公钥/私钥进行SSL的一般性了解.根据我的理解,我可以清楚地看到如何使用证书来建立安全连接并安全地传输数据.但是我不明白它们如何用于客户端身份验证,因为证书包含公钥并且不保密.

我有几个问题:

我在哪里可以阅读有关SSL和证书如何用于客户端身份验证的信息?

即使证书未公开......通过在浏览器中访问HTTPS URL,我可以查看并保存证书.然后,我可以将证书打包到密钥库中,并从应用程序中使用它.

Jeremy Huiskamp 在这篇文章中写道

客户端身份验证将在服务器请求时自动执行

...所以客户端身份验证以及数据加密可以使用证书执行吗?

编辑回答我的问题的第一部分:客户端密钥库不仅应包含服务器的公钥,还应包含客户端的私钥.然后服务器必须能够使用客户端的公钥解密?这是否意味着密钥库应该有两个证书?

Bru*_*uno 10

首先,快速了解公钥加密术语:

  • 你使用私钥签名和解密/解密,
  • 验证(签名)并使用公钥加密/加密.

(您实际上并没有使用公钥"解密".)

在使用或不使用客户端身份验证的情况下使用SSL/TLS,服务器会提供一个证书(*),其中包含私钥.服务器在SSL/TLS握手期间(在连接开始时)发送其证书,并且能够解密客户端使用其私钥(它保持私有)发送的内容.私钥和证书存储在服务器的密钥库中(如果未在Java中实现,则存储在等效密钥库中).

作为此项的一部分,客户端使用其信任库(一种包含可信证书的密钥库的形式)来验证服务器证书.服务器证书可以通过显式位于信任库中来信任,或者在大多数情况下通过链接到信任库(PKI)中的可信CA证书来信任.

Java中密钥库和信任库之间的术语可能有点令人困惑,您可以在此答案中找到更多详细信息.

关于您的问题,客户端的信任库不包含服务器的公钥,而是包含其证书或可以验证的CA证书.(这不仅仅是拥有公钥,而是知道它是谁,使用证书中的其他信息.)

除此之外,当您使用客户端证书身份验证时,服务器端还有一个信任库(或等效服务器),客户端端也存在一个密钥库,因为为此目的,角色是相反的.

在使用客户端身份验证的SSL/TLS握手中,服务器从发送它的客户端请求证书(如果可用).

在握手结束时,客户端发送一条CertificateVerify消息,该消息使用客户端证书私钥对客户端和服务器之间到目前为止交换的所有消息进行签名(这是两者都知道的).然后,服务器能够根据作为此交换的一部分获得的客户端证书中的公钥来验证此签名.这向服务器证明,客户端的任何人都拥有与其发送的证书中的公钥对应的私钥.

服务器的下一步是验证是否信任该证书,即是否信任身份和公钥之间的绑定,如证书中所示和"密封".这通常使用PKI完成,您可以根据已知的CA检查证书,或者如果您的部署环境足够小,则针对一组固定的可信证书.(可以有其他验证方法,但它们的可用性实际上取决于您要部署此系统的情况.)

因此,对于你的第二个问题:

  • 客户端密钥库至少应包含客户端的证书及其私钥.
  • 客户端信任库应包含服务器证书或可用于验证服务器证书的CA证书.

由于密钥库和信任库都是用于不同目的的密钥库(在存储格式意义上,通常是文件),因此通常可以使用相同的密钥库来同时满足密钥库和信任库的目的.

(*)有些密码套件不依赖于证书,但对于这个问题来说,这是不寻常的和偏离主题的.