加密/解密多个密钥的功能

162

是否有可能加密数据,以便可以用多个不同的密钥进行解密?

例如:

我已经用key1加密了数据,但我希望能够使用keys 2、3和4进行解密。

这种情况是否可行?


1
当前的答案似乎实际上是多次加密一个常见密钥,这会使得头部长度随着每个添加的接收者成比例增加。我敢打赌有一种方法可以产生所需的效果,在此方法中,多个密钥可以使用模逻辑解密同一条消息。当然,这个概念的一个副作用就是,许多密钥都可以解密,不仅仅是你知道的那些,但这可能是无关紧要的,就像许多输入可以产生相同的哈希值,而不仅仅是你知道的那个输入一样。只要熵足够高。我想知道基于模数的密钥方案是否会存在? - Albert Renshaw
5个回答

220

GnuPG标准支持多密钥加密。

以下命令将使用Alice的公钥和Bob的公钥对doc.txt进行加密。 Alice可以使用她的私钥解密。 Bob也可以使用他的私钥解密。

gpg --encrypt --recipient alice@example.com \
    --recipient bob@example.com doc.txt

这个功能在用户指南的章节 "加密和解密文件" 中详细介绍。


同样。知道如何做这件事很酷,但我找不到关于它的任何手册页。 - MarkusQ
@Mitch,我发布了一个答案,可能会有我们的答案!(请测试并评论是否如此/否则-非常感谢!) - pythonlarry
@MarkusQ,看一下我给Mitch的链接(https://dev59.com/3XjZa4cB1Zd3GeqPclb6#20581497)。如果你能测试并感谢一下就好了! :-) - pythonlarry
这样会生成一个加密文件,可以使用任意一个私钥进行读取,而不是每个密钥对应一个文件? - user8675309
16
是的,数据是由一个共同的对称密钥加密的。每个接收者的公钥只加密对称密钥,而不是为每个接收者重新加密整个数据。 - wisbucky
以上命令中的共享对称密钥在哪里?以上命令是否会生成与收件人数量相等的文件数? - cogitoergosum

77

可以实现

加密多个接收者是可能的。当你想读取你发送给某人的内容时,你需要在接收者列表中,这似乎很合理。

命令行

以下是通过gpg命令行实现的方法(如David Segonds的答案中所述):

gpg --encrypt \
  --recipient alice@example.com \
  --recipient bob@example.com \
clear-message.txt

GUI客户端

您的图形用户界面必须提供一种为多个人加密的方式。

机制

信息安全上有一个问题,GPG文件与多个接收者的大小?,该问题解释了加密机制:

GPG使用对称密钥加密文件一次,然后放置一个标头,用于识别目标密钥对和对称密钥的加密版本。

[...] 当加密给多个接收者时,这个标头被多次放置,为每个接收者提供了同一对称密钥的唯一加密版本


11
特别感谢最后两句话:它们使一切变得清晰明了! - radistao

45

GnuPG和PGP客户端通常使用称为“会话密钥”的对称密钥加密实际数据。然后,会话密钥会被用每个“接收者密钥”(即您使用-r/--recipient指定的密钥)进行加密。这有时被称为混合密码。目前,我相信GnuPG默认使用256位的会话密钥和AES将明文数据加密到该AES-256会话密钥,而您的接收者密钥在这种情况下是您的RSA/DSA/ECDSA等非对称密钥。

采用这种方式的原因之一是对称加密算法(如AES)通常比非对称加密算法(如RSA)快得多。因此,GnuPG只需使用RSA加密约256位(会话密钥),并可以使用AES使用该会话密钥加密数据(大小随意!)。甚至Intel机器还具有内置指令AES-NI,可通过硬件执行算法的某些步骤,使GnuPG在加密/解密数据方面更加快速。

另一个采用这种方式的原因是它允许将PGP加密文档加密给多个人而不必使文档大小加倍。请注意,当您为加密文档指定多个接收者(例如,gpg -ea -r Alice -r Bob -o ciphertext.asc)时,存储的加密文档(ciphertext.asc)并不比只加密给Alice的文档大两倍。

另请参见gpg手册页中的--show-session-key参数,以便仅解密会话密钥,例如允许第三方解密已加密为您的文档,而无需将私钥或明文数据传输给他们。


3
感谢您对加密文档不会因签署人数 n 倍而变大的解释。 - hummmingbear

7
是的,这是可能的。首先可以在Google上搜索“多方加密”进行了解。
据我所知,目前没有成熟的软件包可供使用。
附注:以下是一种实现方式的草图。加密消息包括:
- 使用一次性密码加密的有效负载 - 使用key1加密的一次性密码 - 使用key2加密的一次性密码 - ... - 使用keyN加密的一次性密码
接收方只需使用其持有的key i对其副本进行解密,然后解密有效负载即可。
但这只是证明它可能被完成,并且作为实际实现将会很差。如果可能的话,应该避免自己编写加密算法。如果您不理解其中的原因,那么您肯定应该避免自己编写加密算法。
-----编辑------------
如果我错了,而Gnu工具可以实现,请使用它们。但我似乎找不到任何有关如何实现的信息。

1
这个可能不太好的地方在于一旦你知道了一次性密码本,你就有了已知的明文以及其他密钥的加密值。利用这些信息,你可能会更容易地找出其他密钥是什么。 - Kibbee
2
谷歌搜索“多方加密”并没有得到太多结果。你可能会在“广播加密”方面有更好的运气,它也包括了这种情况。 - staktrace
1
@Kibbee:密钥并不是秘密,它们是公开的。因此,使其更容易找到并不重要。(这些方案仅用于仅可用于加密而非解密的密钥。) - David Schwartz
5
我很确定实际的实现并没有使用共享的一次性密码本(这需要与明文和密文一样大,从而使消息大小加倍),而实际上使用了共享的对称加密密钥(通常比消息小得多)。 - Joachim Sauer

-21

多个(两个以上)密钥RSA可能是这样的 - 我不是数学家,所以这个算法未必安全,我只是想给出一个大概的想法。

m=p*q*r; p、q、r为大质数

fi(m)=(p-1)(q-1)(r-1)

d==(e1*e2*e3*...*ei)^(-1) (mod fi(m)); e1...ei是任意数字,d被计算出来以满足等式

y1==x^e1 (mod m)

y2==y1^e2 (mod m)

y3==y2^e3 (mod m)

...

x==yi^d (mod m)

这个算法可以用来提高洋葱路由器的速度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接