加密 - 我应该使用 RSA 还是 AES?

信息安全 AES RSA
2021-09-07 17:56:04

我的模型是我有几个客户希望与其他一些(但不是全部)客户交谈的模型。

所有消息都将通过服务器发送。

只有相互通信的两个客户端应该能够知道该消息。所以服务器和其他客户端应该无法确定发送了什么消息。

两个客户端之间的通信可能一天开始和结束几次。

消息将是可能无限长度的纯文本,但可能要少得多,想想 SMS 风格的消息。

鉴于这些情况,我应该如何加密消息?如果可以提高速度或效率,我不介意编写额外的代码。

我知道 RSA 和 AES 如何工作的粗略基础知识,但我不知道什么是最好的。

当您为 RSA 生成公钥/私钥对时,是否存在需要生成新密钥对的情况?或者一个客户可以拥有一个公钥并将相同的密钥提供给想要与他交谈的任何人并且只有他能够(曾经)阅读消息,但他们存储所有未来消息的公钥?

或者我应该为一对客户端提供一个单独的对称 AES 密钥,并在首次启动联系时简单地共享它并永远使用它。同样,是否有任何情况需要再次生成?

如果客户端崩溃/关闭/重新启动,我将如何存储密钥以便它们持续存在?

4个回答

都不是,除非两者兼而有之。你问错问题了在这个阶段你不应该考虑加密算法,而应该考虑加密协议。

加密协议很难设计,并且是安全漏洞的常见来源。您不完全了解公钥密码学,因此您还没有准备好在自己的密码协议中使用它。

在高层次上,您的模型适用于公钥加密(例如 RSA)。让每个客户端都有自己的私钥,并将其公钥发布给其他客户端。客户端的私钥不会随着时间的推移而改变,除非客户端已被泄露。对称密码术(例如 AES)在这里不能很好地扩展,因为每客户端都需要有自己的密钥。

尽可能使用现有软件。实现加密协议几乎和设计它们一样棘手。对于客户端偶尔向彼此发送消息的模型(电子邮件样式),一个很好用的工具是GnuPG(对于双向通信,请使用SSL/TLS。)

所以:对于日常操作,发送消息,调用gpg,用收件人的公钥加密,当你在它的时候用发件人的私钥签名。收到消息时,根据声称的发送者的公钥检查签名,并使用接收者的私钥解密。换句话说,发送 withgpg --sign --encrypt -r NAME_OF_RECIPIENT 和接收 withgpg --verify后跟gpg --decrypt.

剩下的问题是密钥分配问题。客户端生成其密钥对后,需要通知其他客户端并分发它,而不允许攻击者在传输过程中截获和替换公钥。如何做到这一点取决于你的很多精确场景。不要忽视这部分的安全性。

如果且仅当调用 GnuPG 被证明太慢时,请考虑使用类似协议的更轻量级的、也许是自制的实现(从电子邮件范围开销到 SMS 范围开销)。在底层,GnuPG 为每条消息生成一个对称密钥,因为公钥加密对于大消息来说是昂贵的;公钥算法仅用于加密对称密钥和签署文件摘要。你应该遵循这个模型。使用 AES 进行对称加密,SHA-256 作为摘要算法,RSA 作为公钥算法是一个不错的选择。

正如 In silico 所说,RSA 和 AES 有两​​种不同的用途。AES 是一种快速算法,适合加密整个对话。但它有一个问题:如何在对方不知道的情况下决定在两方之间使用哪个密钥?

RSA 可以解决这个问题。如果每个参与者都拥有其他所有参与者的公共 RSA 密钥,那么任何人都可以开始与其他任何人进行加密通信(通过使用其他参与者的公共密钥)并决定要使用的秘密 AES 密钥。一旦确定了 AES 密钥,就可以使用 AES 加密对话的其余部分。为了向参与者 B 证明确实是 A 想要与他交谈,可以使用数字签名。

我所描述的是,grosso modo,当浏览器连接到启用 SSL 的 Web 服务器时,SSL 握手会做什么。

不要采取错误的方式,但是...

我知道 RSA 和 AES 如何工作的粗略基础知识,但我不知道什么是最好的。

如果您只了解基础知识,那么您可能不是解决此问题的合适人选(目前)。安全是您必须非常特别和小心的领域之一,否则您会使整个安全设置无效。

此外,我认为我们没有足够的信息来给你一个正确的答案。必须事先了解有关安全预期的业务合同。

在大多数情况下,出于安全原因,密钥永远不会离开生成它们的机器,因此如果您打算“共享”信息,那么从纯粹的安全角度来看,公钥解决方案通常是正确的选择。例外情况是您是否可以以安全的方式共享对称密钥,例如通过物理媒体将密钥发送给该人。

基本上,使用公钥加密(如 RSA)比使用对称密钥加密(如 AES)要贵得多,而且当有很多消息从一个到另一个传递时,最好使用对称钥匙。

现在,可以使用公钥加密来完成对称密钥的创建和交换。

例如:

每个客户端都有一个私钥-公钥对,公钥存储在服务器上。当两个客户端开始通信会话时,每个客户端都从服务器获取对方的公钥并向对方发送一个加密数字。然后每一方对这两个数字进行哈希处理,并将结果用作从现在开始加密/解密数据的密钥。