概述
TwoForOne是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点在于RSA加密算法。
题目分析
相关的任务文件包括两个RSA公钥文件key1.pem和key2.pem,以及相对应的两个密文文件message1和message2. 任务说明中则提示相同的明文被加密两次。
## 解题过程
首先获得RSA公钥文件所提供的参数,
```python
from Crypto.PublicKey import RSA
with open('key1.pem') as f:
key1 = RSA.importKey(f.read())
with open('key2.pem') as f:
key2 = RSA.importKey(f.read())
key1为
RsaKey(n=25080356853331150673712092961488349508728123694382279186941974911344272809718201683391687288116618021523872262260746884803456249468108932413753368793568123710905490623939699616018064364038794824072468125668702688048418916712950393799664781694224559810656290997284081084848717062228887604668548576609649709572412523306016494962925450783098637867249337121156908328927249731928363360657779226929980928871118145919627109584218577535657544952661333527174942990937484743860494188129607347202336812042045820577108243818426559386634634103676467773122325120858908782192357380855678371737765634819794619802582481594876770433687, e=65537)
key2为
RsaKey(n=25080356853331150673712092961488349508728123694382279186941974911344272809718201683391687288116618021523872262260746884803456249468108932413753368793568123710905490623939699616018064364038794824072468125668702688048418916712950393799664781694224559810656290997284081084848717062228887604668548576609649709572412523306016494962925450783098637867249337121156908328927249731928363360657779226929980928871118145919627109584218577535657544952661333527174942990937484743860494188129607347202336812042045820577108243818426559386634634103676467773122325120858908782192357380855678371737765634819794619802582481594876770433687, e=343223)
我们可以得知这两个公钥文件的n值相同,但e值不同。 并且e1和e2互质。 根据RSA加密算法,在这种情况下,可以使用如下公式获得明文。
其中c1和c2是两个密文,a和b则是满足贝祖等式a * e1 + b * e2 = gcd(e1, e2)的系数。
首先从密文文件获取c1和c2, 注意两个密文文件都使用base64编码。
import base64
from Crypto.Util.number import bytes_to_long, long_to_bytes
with open('message1') as f:
data = f.read()
ciper_text_1 = bytes_to_long(base64.b64decode(data))
with open('message2') as f:
data = f.read()
ciper_text_2 = bytes_to_long(base64.b64decode(data))
然后使用扩展欧几里得算法计算a和b, 这里使用的是SymPy库。
from sympy.core.numbers import igcdex
a, b, gcd = igcdex(key1.e, key2.e)
最后使用上述的公式计算得到明文。
m = pow(ciper_text_1, a, key1.n) * pow(ciper_text_2, b, key1.n)
m = m % key1.n
message = long_to_bytes(m)
print(message)