两个以上收件人的非对称加密?

Asymmetrical encryption for more that two recipients?

我想创建一个应用程序,其中多人应该能够安全地相互通信(想想分散的群聊)- 听起来很容易,但这是我的问题:

据我了解,使用非对称加密,您有一个 public 密钥和一个私钥。每个想要向某人发送消息的人都必须使用 public 密钥对其进行加密,而收件人可以使用私钥对其进行解密。
但是如果有两个以上的人应该能够阅读所有消息,我不知道这应该如何工作... 要么每个人都有 public 和私钥——我认为这是个坏主意——或者每个人都必须拥有每个人的 public 密钥,并且必须向每个收件人发送单独的消息。
另外,我想百分百确定,发消息的人真的是他假装的那个人。 (所以没有人能够 "fake" 消息)

是否有解决我问题的加密算法?

我假设你指的是非对称加密,而不是异步加密。

在大多数情况下,我们实际上并不使用非对称密码来加密消息的内容。这是因为消息可能很大,而且与对称密码相比,非对称密码的速度较慢。这也是因为你在这里争论的问题:在多方通信中,你希望能够只发送一次消息并让每个人都能够阅读它。所以诀窍是我们将非对称和对称技术结合到一个解决问题的协议中。

首先,我们生成一个随机对称密钥,我们可以称之为 "session key"。我们打算将此会话密钥分发给所有收件人,但我们需要安全地进行此操作。这是我们实际要使用非对称加密的地方。我们使用每个 public 密钥和非对称密码(例如 RSA)为每个收件人加密一次会话密钥,然后将加密的会话密钥发送到每个 recipeint。我们可以将它分别发送给每个收件人,或者我们可以构建一个如下所示的结构:

"recip1|recip1EncryptedSessionKey|recip2|recip2EncryptesSessionKey..." 

并将整个内容发送给所有收件人,每个收件人都可以解析它并解密他们自己的会话密钥的加密副本。 (这通常是加密电子邮件的处理方式:所有收件人的会话密钥的所有加密版本的列表包含在邮件中,每个人都会收到完全相同的电子邮件。)

一旦我们将会话密钥安全地分发给所有收件人,我们就可以使用会话密钥使用对称密码(例如 AES)对每条消息加密一次,然后将相同的加密消息发送给所有收件人。由于他们都收到了会话密钥的副本,因此他们都可以阅读并采取行动。

请注意,在与加密有关的所有事情中,至关重要 会话密钥确实是随机的。不要仅仅依赖普通的普通随机数生成器,看在老天的份上不要自己动手。确保使用 cryptographically secure pseudorandom number generator.

真正的聊天系统可能会复杂得多,可能具有定期重新建立新会话密钥的机制,并且安全协议的细节可能非常复杂。即,考虑如何防止坏人介入并欺骗所有人使用他选择的会话密钥!但基本情况如上

控制收件人组的扩展

to ,你问

Is it possible with this algorithm to ensure that only one is able to invite others? As far as I understood, everybody could distribute the decrypted session key.

在群聊场景中应用该协议时,请不要让术语 "session key" 误导您。相反,将对称加密的密钥视为 "message key":每次有人向组发送消息时,他们应该生成一个新的随机对称密钥,分别使用每个合法接收者的 public 密钥对其进行加密,然后将所有这些密码添加到对称加密的消息中。这样,每个发件人都可以独立决定他们认为谁是他们自己发送的邮件的合法收件人组的一部分。

这会给协议带来更多的传输开销,但这在实践中可能无关紧要。重要的是 'cost' 获得更大量的 'good' 随机性(熵)以生成足够不可预测的消息密钥。因此,一个可接受的优化可能是,如果合法收件人组保持不变,发件人可能会重新使用他们自己先前发送的消息的会话密钥。他们永远不应该重新使用从另一个组成员收到的会话密钥来发送他们自己的消息。

当然,即使每个发件人独立决定他们认为谁是他们邮件的合法收件人,您也无法阻止任何合法收件人泄露他们收到的邮件:他们可以简单地转发未加密(或为某人加密)的邮件不在原始收件人组中)给他们想要的任何人。

确保真实性

在对原始问题的编辑中,您添加了

Also, I want to make a 100% sure, that the one who sends a message really is who he pretends to be. (so nobody is able to "fake" messages)

加密无​​法做到这一点,但密码学有另一种方法可以确保

  • 消息实际上来自声称发送它的人
  • 以来邮件未被篡改

确保这些事情的方法是签名,这也是public-私钥密码术启用的东西。让发件人使用他们的私钥签署他们的消息。 (这通常意味着 'encrypting' 使用私钥对消息进行加密安全散列。)并让接收方验证签名(通过 'decrypting' 签名与发送方的 public 密钥并比较结果使用他们自己计算的消息的哈希值。)

不要自己滚动任何东西(除非你应该)

Richard 的回答建议您不要使用自己的(伪)随机数生成器。对于您计划在生产中使用的任何内容,我会将其扩展为 anything 加密:

  • 不要发明自己的协议
  • 不要发明自己的密码、签名或哈希函数
  • 不要发明你自己的收集熵的方法
  • 不要推出自己的实现上述任何内容,即使是由其他人发明的

而是使用完善的加密库。这些由加密理论和编写安全软件实践方面的专家撰写和审阅。尽管这些库经常被发现存在(有时令人尴尬的)安全问题,但您自己想出的任何东西都不会像它们一样安全。

尽管如此,对于学习,实施任何或所有列出的内容(包括伪随机数生成器)是很好的练习,至少可以帮助您了解底层密码学的某些方面.这种理解很重要,因为正确和安全地 使用 完善的库通常很困难,即使您 do 对他们通过界面揭示的概念。

当然,对于密码学中的创新,发明新东西(并让该领域的专家社区对其进行仔细审查)也是必要的。那个新东西不应该用于任何严肃的事情之前它已成功通过审查。