如何与 RSA public/private 密钥和 GnuTLS 形成 TLS 连接?

How to form TLS connection with RSA public/private keys and GnuTLS?

我正在编写 client/server TCP 程序并希望使用 TLS 加密和验证连接。我的计划是让客户端向服务器提交 public RSA 密钥,然后使用私钥和用户名来验证客户端的身份并加密连接。

GnuTLS 文档还有很多不足之处,但我找到了一个很好的 PSK 示例并尝试对其进行调整以使用 RSA 非对称密钥。在解决了这个问题之后,特别是文档没有清楚描述的各种晦涩的微妙之处,我让客户停止抱怨 "No supported cipher suites have been found" 但现在服务器抱怨了。

在互联网上进行更多搜索后,我发现了一个测试程序,它是 GnuTLS CI 的一部分,用于测试 RSA-PSK,我意识到共享密钥仍然是对称的。 RSA-PSK 和我想的不一样。

我真的不喜欢使用对称密钥,因为它需要以明文形式存储在服务器端,因此不安全。

然而,简要查看 RSA 密钥交换表明不涉及用户名,它实际上是基于证书的,服务器使用自己的私钥,而所有客户端使用相同的 public 密钥。因此无法保证客户的身份。

在花了一天时间尝试让 TLS 工作之后,我不愿意重新发明轮子(这总是存在安全风险)我想在这里问一下,以防有任何专家可以建议我如何实现我想要实现的目标。

想到的唯一解决方案是相当肮脏和骇人听闻的(并且重新发明轮子),即实现预 TLS 握手握手,其中客户端生成随机密钥,使用其私钥对其进行加密,然后将它和用户名发送到服务器,然后服务器使用 public 密钥对其进行解密。然后 GnuTLS 可以使用随机密钥使用正常的对称 PSK 密钥交换。

我不明白为什么 GnuTLS 不实现这样的东西。我所期望的是 GnuTLS 客户端将用户名发送到服务器,然后服务器通过生成加密密钥来执行密钥交换,并使用客户端的 public 密钥对其进行加密,并将加密后的密钥发送到客户端。客户端使用其私钥解密密钥,你看,密钥交换已安全完成并且 TLS 通道已打开。

总而言之:

1) 如何实现我需要实现的目标(最好使用 GnuTLS)?

2) 为什么 RSA-PSK 没有像我预期的那样工作,而是使用对称密钥和证书?

TLS 不适合我试图表达的目的。 Libssh 可能是最好的解决方案,但我已经使用 libgcrypt 完成了一个完整的解决方案,所以...