首页 密码学

附件为一个压缩包,里面有
flag.enc,pubkey.pem;根据文件名我们知道应该是密文及
公钥
使用 openssl 从公钥中分离出 e 和 n,命令如下:

openssl rsa -text -modulus -pubin -in pubkey.pem

-text 以纯文本格式输出
-modulus 输出模数
-pubin 读出公钥内容
-in 读入文件
Exponent: 65537 (0x10001)
Modulus=C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
将模数转为 10 进制:
n=87924348264132406875276140514499937145050893665602592992418171647042491658461
e=65537
在线分解大素数 http://www.factordb.com/
也可以用这个库自己分解 libnum.factorize(n)自己分解
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
根据 p,q 求 phi,根据 e 求逆元 d,用 c^d mod n 求得明文
脚本如下:

import gmpy2
import libnum
# import struct
'''
#这是注释
n=pq
phi =(p-1)(q-1)
ed=1 mod phi
'''


'''

#这是注释
import libnum
 libnum.n2s(n)数字转字符串
 libnum.s2n(s)
 libnum.factorize(n) 大整数分解
gmpy2.mpz(n)初始化一个大整数
n=invert(m,phi)求 mod phi 的逆元
pow(c,d,n)求 c^d mod n
gmpy2.is_prime(n) 素性检测
gmpy2.gcd(a,b) 欧几里得算法,最大公约数
gmpy2.gcdext(a,b) 扩展欧几里得算法
gmpy2.iroot(x,n) x 开 n 次根 
'''



#将文件中读出的二进制 Byte 类型数据转为数值
def bytes2num(b):
    s='0x'
    for x in b:
        tmp=str(hex(x))[2:]
        if len(tmp)==2:
            pass
        else:
            tmp='0'+tmp
       # print(tmp)
        s+=tmp
        num=int(s,16)
    return num
#将 10 进制数值按照 ascii 码转为字符串
def num2str(n):
    tmp=str(hex(n))[2:]
    if len(tmp)%2==0:
        pass
    else:
       tmp='0'+tmp
    s=''
    for i in range(0,len(tmp),2):
        temp=tmp[i]+tmp[i+1]
        s+=chr(int(temp,16))
    return s
fi=open('flag.enc','rb')
cipher=fi.read()
cipher=bytes2num(cipher)
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
phi=(p-1)*(q-1)
n=8792434826413240687527614051449993714505089366560259299241817164704
2491658461
e=65537
d=gmpy2.invert(e,phi) 
message=gmpy2.powmod(cipher,d,n)
print(num2str(message)) 



文章评论