RSA初步了解
一、首先认识rsa是一种非对称加密算法。
对称加密:加密解密使用同一个密钥,加密者接受信息采用密钥加密,而到破译者手中还是使用这份密钥。这种方式的优点是加密效率高、加解密速度快,但是缺点是密钥需要共享,如果密钥被泄漏,则加密无效。
非对称加密:加密解密使用不同的密钥,加密使用的是公钥,解密使用的是私钥,因为公钥可以公开,所以只有私钥知道的加密信息能够被解密,这种方式的优点是安全性高,缺点是相对于对称加密而言,加密速度较慢。
二、RSA所需元素
一对质数p,q
公共模数N = p * q
欧拉函数φ(N) = (p-1) * (q-1) = L
公钥e条件:
1 < e < L
gcd(e,L) = 1
私钥d条件:
1 < d < L
(e * d) mod L = 1
gcd(a,b):取a和b的最大公约数
mod:取余运算。 例:10 mod 3 = 1(也可写成(e * d) % L = 1)
三、加解密过程
四、已知e求d及m明文方法(一般是由e推出d)
求私钥和明文一般利用python的gmpy2库函数进行计算。
私钥d = gmpy2.invert(e,L)
明文m(plaintext) = gmpy2.powmod(ciphertext,d,N)
求flag一般利用python的binascii库函数进行计算。
flag = binascii.unhexlify(hex(m)[2:]).decode("utf-8")
说明:
1.invert函数用于计算模反。模反是指对于给定的整数a和模数m,找到一个整数b,使得(a*b)mod m = 1。
2.powmod(a,b,c)用于计算a的b次幂取余c的结果,对应ciphertext的d次方取余N。(上图解密)
3.binascii库在 Python 中用于在二进制数据和ASCII字符串之间进行转换,unhexlify用于将十六进制表示的数据转换为其对应的字节对象,hex(m)将明文转为16进制,[2:]切片是将0x去除,最后decode()将字节数据转换为字符串数据以utf-8形式。
补充:e与L的最大公约数为1(互质),在所有e的可取值中取最小的数(特点)。
signln——reserve
64位无壳,ida打开。
红框几个数字较可疑。
__gmpz_init_set_str(a,b,c):取b的c进制数存储到a中。
__gmpz_powm(a,b,c,d):b的c幂次方取余d存储到a中。
__gmpz_cmp(a,b):比较a和b是否相等,相等返回0,否则为1。
由以上函数及数据特性可以推测:
混杂字母和数字的为密文,全是数字最长的为共模数N,最小的65537为公钥e。
N利用网站可以得出p,q。
网址:http://www.factordb.com/index.php?query=103461035900816914121390101299049044413950405173712170434161686539878160984549
脚本如下:欢迎各位师傅指正!
import gmpy2
import binascii
N = 103461035900816914121390101299049044413950405173712170434161686539878160984549
ciphertext = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
#16进制加上0x
e = 65537
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
L = (p-1)*(q-1)
#print(L)
D = gmpy2.invert(e,L)
plaintext = gmpy2.powmod(ciphertext,D,N)
flag = binascii.unhexlify(hex(plaintext)[2:]).decode("utf-8")
print(flag) #flag{Pwn_@_hundred_years}