2017-10-12 169 views
0

我正在编写客户端/服务器TCP程序,并希望使用TLS加密和验证连接。我的计划是让客户端将公共RSA密钥提交给服务器,然后使用私钥和用户名来验证客户端的身份并加密连接。如何与RSA公钥/私钥和GnuTLS形成TLS连接?

GnuTLS文档留下了很多不足之处,但我找到了一个很好的PSK示例,并试图使其适用于使用RSA非对称密钥。在我对这个问题进行了猛烈的抨击后,特别是文档中没有清楚描述的各种晦涩的微妙之处,我已经让客户停止抱怨“没有找到支持的密码套件”,但现在服务器确实如此。

在更多的互联网搜索之后,我发现一个测试程序是GnuTLS CI的一部分,测试RSA-PSK,我意识到共享密钥仍然是对称的。 RSA-PSK不是我认为的那样。

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

但是简要介绍一下RSA密钥交换表明,没有涉及用户名,它实际上是基于证书的,并且服务器使用自己的私钥,而所有客户端使用相同的公钥。因此,不可能保证客户的身份。

花了一天的时间试图让TLS工作,并且厌恶重新发明轮子(这总是一种安全风险),我在这里问的是,如果有专家谁可以告诉我如何实现我正在寻求实现。

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

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

因此,在总结:

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

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

+0

在阅读了几次后,我仍然不知道你想做什么。也许我们可以从基础开始:好的旧标准服务器认证的TLS有什么问题? –

+0

我需要验证客户端,而不是服务器。如果攻击者欺骗服务器,他们什么也得不到。我试图实现的更像是一个SSH连接,只有某些客户端可以连接,并且他们需要能够证明他们的身份。我想通过公钥验证。这一切都在第一段中介绍。我也想避免证书签名链的复杂性。 – AlastairG

+0

我也想加密数据连接。我不想使用PSK,因为它是对称加密。如果我们的数据库受到攻击,攻击者可以访问我们的系统(尽管如果他们可以抓取数据库,他们也可以做其他事情,但仍然可以)。 SRP看起来很狡猾 - 没有真正的解释它是如何安全的。无论您是为密钥交换目的发送密码还是密码错误,它仍然看起来像是以明文形式发送的。 – AlastairG

回答

0

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