加密顺序与解密顺序可以不同吗?

5

是否可以在一个顺序中进行加密,在另一个顺序中进行解密?例如,我有以下内容:

  • plain_text.txt
  • 公钥/私钥对1
  • 公钥/私钥对2

示例

加密:

public1(public2(plain_text.txt))

解密:

private1(private2(encrypted))

有没有一种加密算法可以实现这个?这种情况是否可能发生?

为什么顺序很重要?更确切地说,为什么顺序需要很重要? - dlamotte
1
使用Blakely-Shamir密钥分割技术,拆分私钥是否对您想要实现的目标有用? - user240438
也许提供一些关于你想要实现什么的背景信息可以帮助解决这个问题... - dlamotte
6个回答

6
在大多数情况下,您无法更改解密的顺序。允许重新排序解密的方案称为可交换加密系统。可以用于构建可交换加密系统的一种公钥加密系统是ElGamal encryption
以下是主要思想:假设g是一个适当群G的生成元,计算离散对数很难。让xA和xB成为两个私钥,hA=gxA和hB=gxB是相应的公钥。两个密钥对都使用相同的群G(即如果我们使用G = Z /(p),则是相同的模数p)。 ElGamal方案的优点之一是,即使两个用户共享相同的群(或模数),它仍然是安全的。另一方面,RSA将不安全。
使用hA加密消息m会产生密文。

(m hAr+r', gr+r')

请注意,知道秘密密钥xA可以解密,因为

(gr)xA = hAr

要再次加密密文,首先需要使用A的公钥重新加密现有密文。 他选择一个随机数r'并计算

(m hAr hAr', grgr') = (m hAr+r', gr+r').

结果只是另一个有效的使用A的公钥加密的结果。 这种重新加密是必要的,以避免攻击,例如对等模数的RSA攻击,如下所示。 接下来,将使用B的公钥进行加密,得到

解密可以按任意顺序进行,例如知道 xA 可以计算出:
(gr+r')xA = hAr+r' 因此可以计算出:
(m hBs, gs),
这正是我们想要的:使用 B 的公钥加密 m。
需要注意一些细节才能得到安全的实现。 而且正确地实现并不容易。 有关更多信息,请参见 Stephen Weis 博士的 Phd of Stephen Weis,其中包含有关可交换加密的章节。
如果使用“教科书RSA”尝试相同的想法,将会有许多问题。首先,为了使加密可交换,用户A和B都需要共享相同的模数。例如,A使用(n,eA,dA),B使用(n,eB,dB),其中n是模数,eA,eB是公钥,dA,dB是私钥。然而,知道例如(n,eA,dA)可以分解n,从而计算出B的私钥,这当然是一个大缺陷。
现在我们可以将m加密为
meA mod n,
再次加密为
meAeB mod n,
使用A的秘密密钥进行解密,得到
meB mod n,
使用B的秘钥解密,以获取m。这看起来很好,直到有人注意到攻击者可以拦截两个密文c = m e A mod n和c' = m e B mod n,然后使用欧几里得算法找到r,s使得
r e A + s e B = 1,
然后计算
m = c r (c') s mod n。
这个想法对另一个答案中提出的使用RC4的解决方案也适用。Weis的论文包含了对该攻击的详细描述。

谢谢,我没有考虑到模数需要相同的问题。我会去了解一下El Gamal算法。 - Anonymous
我已经重写了大部分答案,以展示RSA为什么不起作用(或者至少不能直接起作用)。 - abc

3
使用大多数公共的RSA实现是不可能的。解密例程期望明文以特定格式(即正确填充)存在,如果不是,则失败。同样,在加密时,它会对明文进行填充,而不是使用原始的blob。
RSA的数学原理允许这样做,只要两个密钥的模数互质(几乎总是成立)。但你可能需要自己编写实现。
另一个问题是明文块的数字值应该小于模数。因此,第一个密钥的模数应该比第二个密钥的模数小,否则不能保证第一个密文将是第二个加密轮的适当明文。
OpenSSL似乎有一个无填充模式,你可以尝试一下。
编辑:通常情况下,在99.9%的情况下,自己设计加密算法是一个坏主意。如果你的兴趣纯粹是学术研究,那么请随意;但如果你想要一个特定的功能(例如加密某些内容以便需要两个不信任的方才能解密),那么你肯定走错了路。
编辑2:如果模数相同,RSA的数学原理允许这样做。删掉第二段。但是,两个密钥共享相同的模数会严重损害安全性。如果Alice有私钥(m,d),Cindy有私钥(m,d')-假设相同的m-那么只要给定Cindy的一个单一明文/密文对,Alice就可以在O(m)时间内确定d'。不好。

1

使用公钥/私钥加密,答案是否定的。PubK1(PubK2(plain.text)) => encrypted.text。您必须使用PrivK2(PrivK1(encrypted.text))进行解密。

但是,如果您使用对称流密码(例如RC4),则可以更改解密顺序(A xor B xor C = C xor B xor A)。但这显然不是公钥/私钥算法。


1

只有当加密算法表现为一种特定类型的数学群时,这才是正确的。大多数(全部?)块加密算法并不是这样的群。


0

据我所知,这应该可以通过对RSA进行轻微修改来实现。但是我不知道有哪些工具可以真正做到这一点。


你确定吗?对我来说,两个不同的公钥会导致相同的密文似乎很奇怪?即:PK1(PK2(text))== PK2(PK1(text))...那不是某种冲突吗? - dlamotte
它不会,但这并不是所需的。所需的是只有拥有PK1就能将其转码为PK2(文本)。 - Pavel Radzivilovsky

0
不,这样是不行的。简单来说,因为一个模数比另一个大,所以你无法保证唯一解密。
编辑:我假设这是 RSA。如果不是,那么我得考虑其他一些方法。
编辑2:如果你总是愿意先使用较小的模数,那么这是可行的。

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