使用 Java 中的 Web of Trust 通过 TLS 进行加密和身份验证
对于我正在编写的程序,我想使用 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 中获取概念来实现我自己的层?
For a program I am writing, I would like to use TLS (or something similar) to encapsulate my application's protocol. This will minimize both the amount of work I have to do as well as the number of vulnerabilities I could accidentally create.
My program is designed to be peer-to-peer although one or more servers provide some services to help one user locate another (it registers IP address/port combos) but do little else. I want to make this system very fault-tolerant so having these servers act as a Certificate Authority is unacceptable because a compromise of a server or its key would affect too many users. Therefore I plan on using a Web of Trust.
The main problem with using TLS is that the original TLS 1.2 specification (RFC 5246) does not provide for using OpenPGP certificates. It seems to be very x.509 centric. RFC 6091, which obsoletes RFC 5081 and extends RFC 5246, makes provisions for an extension to TLS that does what I want. The problem is that I don't think BouncyCastle implements this extension and I can't find a Java crypto library that does. I also don't want to write my own / contribute to BC because I'm really bad at not making mistakes and I'm also very lazy.
Another problem with this is that BouncyCastle provides "a light weight client-side TLS API" but because this software is P2P, a server-side API is also necessary so that I can use TLS by making it believe that the peer originating the connection is the client. I'm pretty sure that once the handshake is complete that it's the same.
Questions:
Is there any way that I can still use TLS (which I highly doubt)? Is there a protocol like TLS that is designed for P2P, or at least can function in this way (like I believe TLS can), but can work with an OpenPGP certificate? If neither is the case, should I pursue the idea explained in this question and implement my own layer taking concepts from TLS?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我知道唯一支持 RFC 6091(即带有 openpgp 证书的 TLS)的库是 GnuTLS 但我不知道是否可以在 Java 中使用类似的东西。或者,您可以复制 SSH 语义,在其中使用自签名存储对等方的公钥
X.509 证书。
The only library that I know to support RFC 6091 (i.e. TLS with openpgp certificates) is GnuTLS but I don't know whether you can use something like that in Java. Alternatively you could replicate the SSH semantics, where you store the public keys of your peers using self-signed
X.509 certificates.
在 TLS 中,X.509 部分实际上被处理为不透明 blob:
按照 TLS 的定义,客户端和服务器都应该使用对等公钥,他们以任何他们认为合适的方式获取该公钥,而这大多超出了 TLS 规范的范围:通过电线仅被视为助手。因此,只要客户端和服务器都期望,在这些 blob 中实际发送 OpenPGP 编码的公钥就不会出现问题 - 并且由于您控制两者上的代码,因此这应该不成问题。
那么你的问题就“简单地”变成了让 TLS 实现接受向你提供 blob 而不会被它们阻塞的问题。据我所知,目前还没有符合要求的纯 Java TLS 实现,因此您可能需要编写一些代码——但我强烈建议您不要摆弄除证书 blob 处理之外的 TLS 协议细节。这些事情很微妙,弱点很容易创造......
In TLS, the X.509 parts are actually handled as opaque blobs:
As TLS is defined, both client and server are supposed to use the peer public key, which they get in any way they see fit and that's mostly out of scope of the TLS specification: the certificates exchanged over the wire are considered as mere helpers. So there would be no problem in actually sending OpenPGP encoded public keys in those blobs, as long as both client and server expect it -- and since you control code on both, this should be no issue.
Your problem then "simply" becomes a matter of making a TLS implementation accept to hand you the blobs without choking on them. I know of no existing Java-only TLS implementation which will fit the bill, so you may have to write a bit of code -- but I urge you not to fiddle with TLS protocol details except processing of the certificate blobs. Those things are subtle and weaknesses are sooo easy to create...
据我所知,Sun/Oracle JSSE 实现仅处理 X.509 TrustManager(您可以自定义它来处理某些扩展,但仍然期望结构有效的 X.509 证书。
可能可以使用 Java 的安全 API 更多,因为您必须更深入地了解 TLS 的 Java 实现。
实现 RFC 6091,但我不确定如何实现,这肯定比调整TrustManager 将 PGP 证书中的密钥材料放入 X.509 证书中,并将初始 PGP 证书(及其所有签名)作为 Blob 放入自定义 X.509 扩展中(因为它或多或少已完成 此处)。这里的问题是互操作性,因为这样的扩展不会成为标准,在 Java 中实现能够理解扩展的 TrustManager 绝对是可行的,并且您不需要深入了解 Java 的 TLS 堆栈的内部结构。只需处理自定义 TrustManager 即可初始化您的 SSLContext。
As far as I know, the Sun/Oracle JSSE implementation only deals with X.509 TrustManagers (which you can customize to handle certain extensions, but would still expect a structurally valid X.509 certificate.
It might be possible to use Java's security API to implement RFC 6091, but I'm not sure how. It's definitely more work than just tweaking the TrustManagers, as you would have to go deeper into Java's implementation of TLS.
Alternatively, if it's for a bespoke server, you could re-use the key material from PGP certificates into X.509 certificates and put the initial PGP certificate (with all its signatures) as a blob in a custom X.509 extension (as it's more or less done here). The problem here would be interoperability, since such an extension wouldn't be a standard. Implementing a TrustManager in Java that is able to understand extension is definitely feasible, and you wouldn't need to dig into the internals of Java's TLS stack, you'd only have to deal with custom TrustManagers to initialize your SSLContexts.