我找到的每个教程都解释了如何使用密钥库文件创建与SSLSocket
的SSL / TLS连接,并使用keytool实用程序手动创建SSL证书后存储SSL证书。
我很想知道如何做同样的事情,但使用动态生成的公钥/证书(短暂)。
在Java中创建RSA / EC密钥对非常容易,为什么我们不能仅将它用于SSLSocket
?这在我看来有两个很大的优点:它允许前向保密,同时我不需要处理Android的密码,实用程序,文件阅读器和密钥库转换器。
答案 0 :(得分:3)
在我看来,这有两个很大的优点:它允许前向保密
前向保密通常涉及像ECDHE或DHE这样的密钥协议(尽管后者因logjam而被广泛弃用)。
是不时重新修改证书的好习惯,不过每个TLS会话都不需要新的证书。
在Java中创建RSA / EC密钥对非常容易,为什么我们也不能将它用于SSLSocket呢?
您也需要X509证书,而不仅仅是一把钥匙。你仍然可以动态制作,但你必须签署证书。证书将是自签名的,或者您需要一个可以根据需要快速签署证书的证书颁发机构。实际上,后者并不存在,意味着握手速度很慢。
如果证书是自签名的,浏览器或任何其他用户代理将不知道如何信任证书,并且使用自签名证书会严重影响TLS的使用。
答案 1 :(得分:2)
作为技术上正确但相当无用的替代方案:
TLS实际上定义了匿名'密钥交换方法DH_anon和ECDH_anon(以及使用它们的密码套件)使用临时密钥对执行前向密钥协议,并且不进行身份验证,因此不需要服务器上的任何证书或密钥库或(可能)信任库客户端。
由于未经身份验证,他们很容易受到主动攻击,因此实际需要安全性的人(和当局)认为他们不能接受使用。 Java(JSSE)确实实现了它们,但默认情况下不启用它们;您的代码必须使用适当修改或设置的列表调用.setEnabledCiphers
。大多数其他SSL / TLS实现要么类似地禁用它们,要么根本不实现它们。
但从技术上讲,这是一种有效的TLS方式,没有长期密钥和证书,因此无需手动管理它们。
顺便说一句,我相信这就是为什么创建一个(SSLContext
和)SSLSocketFactory
与(KeyManager
)一个不包含有效privateKeyEntry的密钥库的原因没有给出错误,因为原则上它可以创建用于匿名连接的套接字(或引擎)。相反,由于实际上从未使用匿名密钥交换,这些工厂会导致所有后续连接以许多非专业程序员无法诊断的方式失败。 (相反,尝试为空信任库创建验证器会引发特定异常,类似于“信任锚集”的内容不得为空。'。