Security Java中通过信任Web的TLS加密和身份验证

Security Java中通过信任Web的TLS加密和身份验证,security,encryption,ssl,bouncycastle,Security,Encryption,Ssl,Bouncycastle,对于我正在编写的程序,我希望使用TLS(或类似的东西)来封装我的应用程序的协议。这将最大限度地减少我必须做的工作量以及我可能意外创建的漏洞数量 我的程序设计为点对点,尽管一个或多个服务器提供一些服务来帮助一个用户定位另一个用户(它注册IP地址/端口组合),但其他功能几乎没有。我想让这个系统非常容错,所以让这些服务器充当证书颁发机构是不可接受的,因为服务器或其密钥的泄露会影响太多用户。因此,我计划使用信任网 使用TLS的主要问题是原始TLS 1.2规范(RFC 5246)没有规定使用OpenPGP

对于我正在编写的程序,我希望使用TLS(或类似的东西)来封装我的应用程序的协议。这将最大限度地减少我必须做的工作量以及我可能意外创建的漏洞数量

我的程序设计为点对点,尽管一个或多个服务器提供一些服务来帮助一个用户定位另一个用户(它注册IP地址/端口组合),但其他功能几乎没有。我想让这个系统非常容错,所以让这些服务器充当证书颁发机构是不可接受的,因为服务器或其密钥的泄露会影响太多用户。因此,我计划使用信任网

使用TLS的主要问题是原始TLS 1.2规范(RFC 5246)没有规定使用OpenPGP证书。它似乎非常以x.509为中心。RFC 6091淘汰了RFC 5081,并扩展了RFC 5246,它为TLS的扩展做了规定,以满足我的需要。问题是,我不认为BouncyCastle实现了这个扩展,我也找不到一个Java加密库实现这个扩展。我也不想为BC写我自己的/贡献,因为我真的不擅长不犯错,而且我也很懒

另一个问题是BouncyCastle提供了“一个轻量级的客户端TLS API”,但由于该软件是P2P,因此还需要一个服务器端API,这样我就可以通过相信发起连接的对等方就是客户端来使用TLS。我敢肯定,一旦握手完成,一切都是一样的

问题: 有什么方法我仍然可以使用TLS(我非常怀疑)?有没有像TLS这样的协议是为P2P设计的,或者至少可以这样工作(我相信TLS可以),但可以与OpenPGP证书一起工作?如果两者都不是,我是否应该遵循中解释的想法并实现我自己的层,从TLS中获取概念


链接到RFCs:和

在TLS中,X.509零件实际上被处理为不透明斑点:

  • 服务器将其证书(以及一些助手证书,如果愿意的话)作为不透明的字节字符串(一个三字节的长度,后跟作为任意字节的编码证书)发送
  • 当服务器请求公钥客户机身份验证时,它会发送一个“名称”列表,这些名称应该是服务器将识别的根CA的编码X.500名称——还有不透明的blob(两字节长度)
  • 客户端在发送证书(链)时使用与服务器相同的格式
根据TLS的定义,客户机和服务器都应该使用对等公钥,它们以自己认为合适的任何方式获得该公钥,这大部分超出了TLS规范的范围:通过网络交换的证书被视为仅仅是助手。所以,只要客户机和服务器都希望,在这些blob中发送OpenPGP编码的公钥就不会有问题——而且由于您控制这两个blob上的代码,所以这应该没有问题


然后,您的问题“简单地”就变成了让TLS实现接受向您提供BLOB而不会阻塞它们的问题。据我所知,现有的纯Java TLS实现不符合要求,因此您可能需要编写一些代码——但我敦促您不要在处理证书blob之外处理TLS协议的细节。这些东西都很微妙,缺点很容易创建…

我知道唯一支持RFC 6091(即带有openpgp证书的TLS)的库是,但我不知道您是否可以在Java中使用类似的东西。或者,您可以复制SSH语义,使用自签名存储对等方的公钥
X.509证书。

据我所知,Sun/Oracle JSSE实现只处理X.509 TrustManager(您可以自定义它来处理某些扩展,但仍然需要结构有效的X.509证书)

也许可以使用Java的安全API来实现RFC6091,但我不确定如何实现。这肯定比调整TrustManager需要更多的工作,因为您必须深入了解Java的TLS实现


或者,如果是定制服务器,您可以将PGP证书中的密钥材料重新使用到X.509证书中,并将初始PGP证书(及其所有签名)作为blob放入定制的X.509扩展中(或多或少都是这样)。这里的问题是互操作性,因为这样的扩展不是一个标准。在Java中实现一个能够理解扩展的TrustManager肯定是可行的,而且您不需要深入研究Java的TLS堆栈的内部,您只需要与自定义TrustManager打交道就可以初始化SSLContexts。

UnfoRTU当然不是这样。TLS握手需要解析证书。这就是RFC 6091扩展到TLS的原因。实际上,我已经实现了TLS客户端和服务器,它们本身没有解析证书。因此,这是可能的。当客户端接收到服务器证书时,它将blob交给一个外部回调,该回调发回要使用的公钥——在我的例子中,回调将blob解释为X.509证书(它对其进行解析和验证),但它肯定会以其他方式对它们进行解释,甚至可能会将它们扔掉,并使用硬编码的服务器公钥,这在某些设置中是有效的。事实上,您的实现将证书作为blob进行处理,这并没有消除TLS解析这些证书的要求。您只是将其委托给回调,但解析仍然没有成功完成协议需要完成。@Nikos,我认为服务器可以选择在不识别证书时不触发致命警报,让应用程序自行进行身份验证/授权(包括证书验证)