签 名 s i g ( m ) = m d ( m o d n ) , 将 其 发 个 收 信 方 , 他 用 公 钥 进 行 运 算 可 以 得 到 : ( s i g ( m ) ) e = m e d ( m o d n ) ≡ m ( m o d n ) 签名sig(m) = m^d (mod\ n),将其发个收信方,\\他用公钥进行运算可以得到:\\ (sig(m))^e = m^{ed}(mod\ n) \equiv m(mod\ n) 签名sig(m)=md(mod n),将其发个收信方,他用公钥进行运算可以得到:(sig(m))e=med(mod n)≡m(mod n)
但是如果源数据太大,用私钥进行运算花时间很长,所以现在一般会用hash函数进行处理
签 名 s i g ( m ) = h a s h ( m ) d ( m o d n ) , 将 其 发 个 收 信 方 , 他 用 公 钥 进 行 运 算 可 以 得 到 : ( s i g ( m ) ) e = h a s h ( m ) e d ( m o d n ) ≡ h a s h ( m ) ( m o d n ) 签名sig(m) = hash(m)^d (mod\ n),将其发个收信方,\\他用公钥进行运算可以得到:\\ (sig(m))^e = hash(m)^{ed}(mod\ n) \equiv hash(m)(mod\ n) 签名sig(m)=hash(m)d(mod n),将其发个收信方,他用公钥进行运算可以得到:(sig(m))e=hash(m)ed(mod n)≡hash(m)(mod n)
密码分析者事先任意搜集一定数量的密文,让这些密文透过被攻击的解密算法解密,透过未知的密钥获得解密后的明文。由此能够计算出加密者的私钥或者分解模数,运用这些信息,攻击者可以恢复所有的明文
用加密算法加密一个较为简单的数,这里我选择的是 x = 2,密文记为r,由RSA原理可知:
x e ( m o d n ) = r r d ( m o d n ) = x x ^e (mod\ n) = r \\ r^d (mod\ n) = x xe(mod n)=rrd(mod n)=x
同理,它所给出的密文c和我们需要求的明文m也有下面式子:
m e ( m o d n ) = c c d ( m o d n ) = m m^e(mod\ n) = c \\ c^d(mod\ n) = m me(mod n)=ccd(mod n)=m
将两个密文相乘,令其等于y:
y = r ∗ c y = r*c y=r∗c
令u为其明文,由欧拉定理可知:
u = y d ( m o d n ) u = y^d(mod\ n) u=yd(mod n)
将y带入可得:
( r ∗ c ) d ( m o d n ) = u r d ( m o d n ) ∗ c d ( m o d n ) = u x ∗ m = u m = u / / x (r*c)^{d} (mod\ n) = u\\ r^d(mod\ n)*c^d(mod\ n)= u\\ x*m = u\\ m = u//x (r∗c)d(mod n)=urd(mod n)∗cd(mod n)=ux∗m=um=u//x
就可以求出明文
yafu
yafu 基本命令:factor(n)
factordb
一个在线分解网站
n比较小的话,可以选择暴力破解
sage有专门因式分解的函数
一般有两个n值,求出其公共因子
如果n1 = pq1,n2 = pq2,可以求出gcd(n1,n2)的公因子
识别此类题目,通常会发现题目给了若干个n,均不相同,并且明文都没什么联系,e也一般取65537
'''
例子:factor跑不出来,通过求公因子,然后分别求出p,q
'''
n1=9051013965404084482870087864821455535159008696042953021965631089095795348830954383127323853272528967729311045179605407693592665683311660581204886571146327720288455874927281128121117323579691204792399913106627543274457036172455814805715668293705603675386878220947722186914112990452722174363713630297685159669328951520891938403452797650685849523658191947411429068829734053745180460758604283051344339641429819373112365211739216160420494167071996438506850526168389386850499796102003625404245645796271690310748804327
n2=132259483961796038160620464187172147926685124136250915699975243642439959919610188941500592078240938374204513752405503100502093989645063185189916201425759266237804115322572307019858216294257220306087220355706904741712592381539470953103035228319716646660675426490344616217256562348690055012934239751847019297291700772802514362161672930585600300890061402243Q75425679571181787206982712477261432579537981278055755344573767076951793312062480275004564657590263719816033564139497109942073701755011873153205366238585665743
特点:m和e都比较小,e一般取3
m e < n , m = c 3 m^e < n ,m =\sqrt[3]{c} me<n,m=3c
有 可 能 稍 微 大 一 点 , m e = k ∗ n + c , m = c + k n e , 枚 举 k 进 行 求 解 有可能稍微大一点,m^e = k*n+c,m = \sqrt[e]{c+kn},\\ 枚举k进行求解 有可能稍微大一点,me=k∗n+c,m=ec+kn,枚举k进行求解
工具:gmpy2
#gmpy2的应用
#!usr/env/python3
import gmpy2
for k in range(10):
gmpy2.iroot(c+k*n,e)
c = m 2 ( m o d n ) c = m^2 (mod\ n) c=m2(mod n)
算是有固定模板,辨别特点,e = 2
这里只关注解密方法,具体看这个https://en.wikipedia.org/wiki/Rabin_cryptosystem
def rabin_decrypt(c, p, q, e=2):
n = p * q
mp = pow(c, (p + 1) / 4, p) #整除 用//
mq = pow(c, (q + 1) / 4, q)
yp = gmpy2.invert(p, q)
yq = gmpy2.invert(q, p)
r = (yp * p * mq + yq * q * mp) % n
rr = n - r
s = (yp * p * mq - yq * q * mp) % n
ss = n - s
return (r, rr, s, ss)
#gmpy2 在python3中安装:
sudo apt-get install libmpfrc++-dev
sudo apt-get install libmpc-dev
sudo pip3 install gmpy2
#gmpy2 在python2.7中安装:
sudo pip install python-gmpy2
#如果还是不行,请用aptitude
安装不成功的看这个安装教程
(这个里面也有一些重要库的安装过程)有兴趣可以看看这个CTF-rsa-tool
使用教程:https://gmpy2.readthedocs.io/en/latest/mpz.html
是python2.7里面的一个库,安装使用请点击libnum
安装:
git clone https://github.com/hellman/libnum
cd libnum
python setup.py install
我们在RSA中常用函数有:
import libnum
libnum.n2s(n) #Number to string
libnum.b2s(b) #Binary to string
libnum.gcd(num1,num2) #求最大公约数
libnum.lcm(num1,num2) #最小公倍数
libnum.s2n(s) #string to Number
libnum.s2b(s) #string to Binar
一个集成工具
已知n,e,p,q,可以求出d
一个有着多种解密算法的python库
安装:
deepin:
sudo pip3 install pycrypto
那个链接里面有这个库的各种用法,想用的可以玩一下
openssl则是SSL的实现版,openssl还包含了公钥私钥的生成、摘要生成等各种工具
linux里面应该是自带的
用法:
#提取公钥信息
openssl rsa -pubin -text -modulus -in [公钥.pem]
#用私钥进行解密
openssl rsautl -decrypt -in [密文.enc]-inkey [私钥.pem]
#其他命令可以看看openssl文档,点击上面那个openssl
另一款强大的rsa解密工具,主要用来生成私钥,具体用法看writeup
这是一个纯python实现的库,不依赖底层文件,优点是部署容易,缺点是速度比较慢
这里有其他方法
由于
e ∗ d ≡ 1 ( m o d ϕ ( n ) ) e*d \equiv 1\ (mod\ \phi(n)) e∗d≡1 (mod ϕ(n))
所以要求d,我们可以先求
ϕ ( n ) = ( p − 1 ) ∗ ( q − 1 ) \phi(n) = (p-1)*(q-1) ϕ(n)=(p−1)∗(q−1)
#RSA实践
#三种解法
'''
第一种gmpy2解法
mpz:Multiple-precision Integers(多精度型整数)
gmpy2.invert():求模逆
'''
import gmpy2
p =gmpy2.mpz(473398607161)
q =gmpy2.mpz(4511491)
e =gmpy2.mpz(17)
fn= (p - 1) * (q - 1)
d = gmpy2.invert(e, fn)
print("d is:")
print (d)
'''
直接用扩展欧几里得法
'''
def computeD(fn, e):
(x, y, r) = ext_euclid(fn, e)
#y maybe < 0, so convert it
if y < 0:
return fn + y
return y
def ext_euclid(a, b):
if b == 0:
return (1, 0, a)
else:
x, y, q = ext_euclid(b, a % b)
# q = gcd(a, b) = gcd(b, a%b)
x, y = y, (x - (a // b) * y) # ‘//’代表整除 ,可以用python演示一下.
return (x, y, q)
p = 473398607161
q = 4511491
e = 17
n = p * q
print("n:"+str(n))
fn = (p - 1) * (q - 1)
print("f(n):"+str(fn))
d = computeD(fn, e)
print(d)
'''
用工具解密——RSAtools
ps:用这个工具记得将e转化为hex形式
'''
根 据 上 述 分 解 大 数 工 具 , 我 们 可 以 求 出 p , q 利 用 ϕ ( n ) = ( p − 1 ) ∗ ( q − 1 ) 求 出 ϕ ( n ) 之 后 求 出 私 钥 信 息 d , 原 理 同 上 , 利 用 m ≡ c d ( m o d n ) 求 出 m 根据上述分解大数工具,我们可以求出p,q\\ 利用\phi(n) = (p-1)*(q-1) 求出\phi(n)\\ 之后求出私钥信息d,原理同上,\\ 利用m \equiv c^d (mod\ n)求出m 根据上述分解大数工具,我们可以求出p,q利用ϕ(n)=(p−1)∗(q−1)求出ϕ(n)之后求出私钥信息d,原理同上,利用m≡cd(mod n)求出m