1. 进入环境,下载附件
题目给的压缩包,包括4个文件,如图:
给出了2个公钥文件和和2个密文文件,用常规的RSA解密方式分别解密,解密失败(n为2048位难以分解)
2. 问题分析
- 继续复习RSA
- 明文为m,密文为c,模数n = p * q
- 使用欧拉函数,φ(n) = (p - 1) * (q- 1)
- 选取一个大整数e,使得gcd(e, φ(n) ) = 1,e用来加密秘钥
- 私钥d可以由欧拉函数值计算出来,满足ed mod φ(n) ≡ 1
- 将明文m加密成密文c:m^e ≡ c (mod n)
- 将密文c解密成明文m:c^d ≡ m (mod n)
- 共模攻击
猜测应该是同一个明文,使用了2个不同的公钥加密得到了不同的密文,对同一明文的多次加密使用相同的模数和不同的公钥指数可能导致共模攻击。
翻看大佬的wp后:https://blog.csdn.net/weixin_44795952/article/details/108933406,明白了什么是共模攻击
所谓共模,就是明文m相同,模n相同,用两个公钥e1,e2加密得到两个私钥d1,d2和两个密文c1,c2
共模攻击,即当n不变的情况下,知道n,e1,e2,c1,c2 。可以在不知道d1,d2的情况下,解出m。
这里有个条件,即
gcd(e1,e2)=1
- 攻击原理
有整数 s 1 s_{1} s1, s 1 s_{1} s1(一正一负),满足:
e 1 ∗ s 1 + e 2 ∗ s 2 = 1 e_{1} * s_{1} + e_{2} * s_{2} = 1 e1∗s1+e2∗s2=1
from Crypto.Util.number import long_to_bytes, bytes_to_long
from Crypto.PublicKey import RSA
from gmpy2 import gcd, invert
def egcd(a, b):
if a == 0:
return b, 0, 1
else:
g, y, x = egcd(b % a, a)
return g, x - (b // a) * y, y
with open('pic/publickey1.pem', 'rb') as f:
f1 = f.read()
pub1 = RSA.importKey(f1)
n = int(pub1.n)
e1 = int(pub1.e)
with open('pic/publickey2.pem', 'rb') as f:
f2 = f.read()
pub2 = RSA.importKey(f2)
e2 = int(pub2.e)
with open('pic/cipher1.txt', 'rb') as f:
c1 = f.read()
c1 = bytes_to_long(c1)
print(c1)
with open('pic/cipher2.txt', 'rb') as f:
c2 = f.read()
c2 = bytes_to_long(c2)
print(c2)
print(gcd(e1, e2))
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
if s1 < 0:
s1 = -s1
c1 = invert(c1, n)
elif s2 < 0:
s2 = -s2
c2 = invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
print(m)
print(long_to_bytes(m).decode())