Python RSA:将加密消息相乘,然后再次对其解密会引发DecryptionError(“解密失败”)

x33g5p2x  于 2023-01-03  发布在  Python
关注(0)|答案(1)|浏览(166)

我想做这样的事情:

#Let m be the initial message
c = rsa.encrypt(m)
new_m = rsa.decrypt( Enc(2m))

现在Enc(2m) = 2^e *c mod n,所以一个懂c的用户也可以使用Enc(2m),我的python代码是这样的:

import rsa
(pub_key, priv_key) = rsa.newkeys(256)
message = 'Journalists belong' 
b_message = b'Journalist belong'        #m should be in bytes
c = rsa.encrypt(b_message, pub_key)     #this is a byte number

n = pub_key.n
c = int.from_bytes(c, byteorder ='big') #turn bytes into int
c = (pow(2, pub_key.e, n) * (c%n)) %n   #compute Enc(2m)
c = c.to_bytes(length = 256, byteorder = 'big')    #turn c back to bytes
new_m = rsa.decrypt(c, priv_key)
4si2a6ki

4si2a6ki1#

我们忘记了填充。rsa.encrypt(m)只是计算pow(m, e, n),而是计算pow(pkcs1_padding(m), e, n),并且内部的pkcs1_padding函数不是乘法函数。
考虑程序的一个小变化,打印出对明文的处理:

import rsa

(pub_key, priv_key) = rsa.newkeys(256)
message = 'Journalists belong'
b_message = b'Journalist belong'  # m should be in bytes
c = rsa.encrypt(b_message, pub_key)  # this is a byte number

n = pub_key.n
c = int.from_bytes(c, byteorder='big')  # turn bytes into int

# now decrypt 'manually' to see the padding

plain_int = pow(c, priv_key.d, n)
print(plain_int.to_bytes(256 // 8, 'big').hex(' '))

c = (pow(2, pub_key.e, n) * (c % n)) % n  # compute Enc(2m)

plain_int2 = pow(c, priv_key.d, n)
print(plain_int2.to_bytes(256 // 8, 'big').hex(' '))

十六进制输出为

00 02 cb de 6a 67 41 f6 f4 6f 3e 67 a2 95 00 4a 6f 75 72 6e 61 6c 69 73 74 20 62 65 6c 6f 6e 67
00 05 97 bc d4 ce 83 ed e8 de 7c cf 45 2a 00 94 de ea e4 dc c2 d8 d2 e6 e8 40 c4 ca d8 de dc ce

第一个具有正确的pkcs-1填充,并且rsa.decrypt()在其上运行将成功无误,而第二个具有字节05,其中rsa.decrypt()期望看到02字节。

相关问题