重复RSA en/解密有时会失败,明文太大

2024-10-02 10:24:07 发布

您现在位置:Python中文网/ 问答频道 /正文

背景:

我尝试在一个简短的明文(例如32字节)上应用一系列RSA加密和解密步骤。每个步骤都有一个专用的RSA密钥,例如2048字节。我使用的是cryptopython包。在

我的第一个问题是:

 keyAlice = RSA.generate(2048)
 print keyAlice.size()

这将打印2047,而不是{}。我必须给出的数字必须是256的倍数,因此尝试使用2049作为输入失败。在

有人能告诉我为什么size()方法返回的大小与我输入的不同吗?在

这种奇怪的感觉不会困扰我,但它可能是关于我主要问题的线索:

对于我的目标,发信人(爱丽丝)应采取几个步骤,例如

  1. 应用Bob的公钥(加密)
  2. 应用Alice的私钥(解密)

(我假设所有钥匙的大小都一样。)

然后接收器(Bob)可以应用相反的方法:

  1. 应用Alice的公钥(加密)
  2. 应用Bob的私钥(解密)

任何加密/解密步骤的结果都会产生一个256字节(2048位)的str。在

Note: Sometimes the result is shorter, e. g. 255 bytes; as I found out this means stripped zero-bytes at the beginning; padding them solves the issue.

如果我把它作为下一步的输入,这就行了

  • 总是,以防只使用加密
  • 总是,以防只使用解密
  • 在加密和解密结合的情况下,大多数情况下都是有效的;
    但有时会失败,从而引发ValueError: Plaintext too large。在

我试图弄清楚在哪些情况下会发生这种情况,哪种类型的输入会导致这种情况发生,但这种情况很少发生(约3%的情况),因此我找不到简单的解释(因此没有解决办法)。在

我的问题是:

  1. 为什么size()方法为2048位密钥返回2047?(见上文。)
  2. 为什么encrypt()decrypt()方法有时对2048位的输入有问题(而它们大多没有处理问题的问题)?在
  3. 如果输入是同一类型的前一个调用的结果(例如encrypt(encrypt(x))从不失败),为什么他们从不有任何问题?在
  4. 如果我级联这些调用的方法由于我还不知道的逻辑原因而注定会失败,那么我如何在应用公钥和私钥的同时又不使每个步骤的输入大量膨胀(例如通过分块)?在

下面是我使用的一些代码来说明问题:

^{pr2}$

Tags: the方法size字节bytes密钥情况步骤
1条回答
网友
1楼 · 发布于 2024-10-02 10:24:07

RSA是一种代数密码体制。它只处理数字而不是字节。加密是通过Enc(m,e,n) := me mod n = c给出的,其中m是消息,e是公共指数,n是模数,c是密文。需要注意的是,m < n必须严格为真。否则,它将无法解密。
为了完整起见,解密是Dec(c,d,n) := cd mod n = Enc(c,d,n)完全相同的操作,其中d是私有指数。在

如果有两个不同的键,则操作如下所示:

c1 := Enc(m,e1,n1)
c2 := Dec(c1,d2,n2)
send c2

现在,如果n2 < n1,那么它可能导致c1 > n2,因此不可解密。并非所有情况下都会发生这种情况,这取决于n1和{}之间的距离。在

如果n2 > n1,那么“sending”将“工作”,但是在接收端,您将颠倒模块的顺序,从而再次运行创建大于模数的恢复消息的可能性。它看起来像这样:

^{pr2}$

不用说,你不应该设计依赖于机会的协议。在


研究方案应该是怎样的

您所追求的协议称为加密然后签名。下面的问题和答案提供了有关该问题的知识和链接的良好缓存:Should we sign-then-encrypt, or encrypt-then-sign?

不管您决定什么,您都需要使用加密和签名生成的填充版本。在pycrypto中,应该使用^{} for encryption和{a3}。请记住,已签名的数据必须可用于接收方的验证。这意味着“用私钥加密”是不可能的,因为接收者无法根据任何东西来检查他们加密的数据。在

发件人:

c := Enc-OAEP(m,e1,n1)
s := Sign-PSS(hash(c),d2,n2)
send c, s

接收人:

ch := Verify-PSS(s,e2,n2)
if ch == hash(c):
    mr := Dec-OAEP(c,d1,n1)
    return mr
else:
    throw Error

Why does the size() method return 2047 for a 2048-bit key?

这看起来像一个bug,不应该发生在this code中。不过,这是一个相当小的错误。在

相关问题 更多 >

    热门问题