密码学学习-Hackergame2021 Easy RSA

密码学学习

Hackergame2021 Easy RSA

题目如下

import math
import sympy
from Crypto.Util.number import *

e = 65537


def get_p():
    x = 11124440021748127159092076861405454814981575144744508857178576572929321435002942998531420985771090167262256877805902135304112271641074498386662361391760451
    y = 11124440021748127159092076861405454814981575144744508857178576572929321435002942998531420985771090167262256877805902135304112271641074498386662361391661439
    value_p = sympy.nextprime((math.factorial(y)) % x)  # Hint:这里直接计算会溢出,请你仔细观察 x 和 y 的特征
    return value_p


def get_q():
    value = [getPrime(256)]
    for i in range(1, 10):
        value.append(sympy.nextprime(value[i - 1]))
    print("value[-1] = ", value[-1])
    # value[-1] = 80096058210213458444437404275177554701604739094679033012396452382975889905967
    n = 1
    for i in range(10):
        n = n * value[i]
    q = getPrime(512)
    value_q = pow(q, e, n)
    print("value_q = ", value_q)
    # value_q = 5591130088089053683141520294620171646179623062803708281023766040254675625012293743465254007970358536660934858789388093688621793201658889399155357407224541324547522479617669812322262372851929223461622559971534394847970366311206823328200747893961649255426063204482192349202005330622561575868946656570678176047822163692259375233925446556338917358118222905050574458037965803154233167594946713038301249145097770337253930655681648299249481985768272321820718607757023350742647019762122572886601905212830744868048802864679734428398229280780215896045509020793530842541217790352661324630048261329493088812057300480085895399922301827190211956061083460036781018660201163819104150988531352228650991733072010425499238731811243310625701946882701082178190402011133439065106720309788819
    return sympy.nextprime(q)

# this destroyes the rsa cryptosystem
p = get_p()
q = get_q()

m = int.from_bytes(open("flag.txt", "rb").read(), "big")
c = pow(m, e, p * q)
print("c = ", c)
# c = 110644875422336073350488613774418819991169603750711465190260581119043921549811353108399064284589038384540018965816137286856268590507418636799746759551009749004176545414118128330198437101472882906564195341277423007542422286760940374859966152871273887950174522820162832774361714668826122465471705166574184367478

分析得知,他是让我们求出q,p从而解RSA得到明文。

1、dir()查找库函数

首先我们解q,因为p还是不会。通过调试,了解到sympy这个库可以获得某质数的下一个质数例如sympy.nextprime(value[i - 1])得到第一个素数下面的素数。查看python某一库下所有函数我们这里选用dir(sympy)找到此函数

2、yafu分解与大数分解

尝试yafu分解的代码:.\yafu-x64.exe "factor(@)" -batchfile data.txt

大数分解的网站 这里

3、md数学公式文本编写超链接

学习如何插入公式 这里

4、百度函数学习

函数math.factorial(y)的意思是求阶乘,求y的阶乘

5、RSA大总结

c ≡ m e   ( m o d   n ) c\equiv m^e\ {(mod \ n)} cme (mod n)

m = pow(c,e,n)
m ≡ c d   ( m o d   n ) m\equiv c^d\ {(mod \ n)} mcd (mod n)
c = pow(m,d,n)对于超级幂取模后期可能会与gmpy2库的powmod()函数有关
ϕ ( n ) = ( p − 1 ) ∗ ( q − 1 ) \phi(n)=(p-1)*(q-1) ϕ(n)=(p1)(q1)

d ∗ e ≡ 1   ( m o d   ϕ ( n ) ) d*e\equiv1\ (mod\ \phi(n)) de1 (mod ϕ(n))
一般情况下求d。 d = libnum.invmod(e, (p - 1) * (q - 1))(这里是libnum库,gmpy2库也可以重点是**invmod()**函数,这是求逆元的函数)
d p ≡ d   ( m o d   ( p − 1 ) ) dp\equiv d \ (mod \ (p-1)) dpd (mod (p1))

d q ≡ d   ( m o d   ( q − 1 ) ) dq \equiv d\ (mod \ (q-1)) dqd (mod (q1))

RSA求解情况

c ≡ m e   ( m o d   n ) c\equiv m^e\ {(mod \ n)} cme (mod n)

1、m,e,n已知,求c

正常情况下m = pow(c,e,n)即可,如果遇到大数,就用m = gmpy2.powmod(c,e,m)这个快(gmpy2库)。

2、c,e,n已知,求m

一般情况下这个是解不出来的,这是RSA加密的基础,知道p,q后即可解出。解体模板如下

import libnum
from Crypto.Util.number import long_to_bytes
 
c = 
n = 
#n = int("",16)
e = 
#e = int("",16)
q = 
p = 
 
d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n)   # m 的十进制形式
string = long_to_bytes(m)  # m明文
print(string)  # 结果为 b‘ m ’ 的形式
3、c,m,n已知,求e

求指数,离散对数攻击

from sympy.ntheory import discrete_log

n = 
m = 
c = 

flag = discrete_log(n,c,m) 

print(long_to_bytes(flag))

4、c,e,m已知,求n

在RSA中一般n是公钥,一般都会给的,如果没给,我在总结上来。

6、大数阶乘求模(威尔逊定理应用)

这里对应求get_p,威尔逊定理
( p − 1 ) ! ≡ − 1   ( m o d   p ) (p-1)!\equiv -1 \ (mod\ p) (p1)!1 (mod p)
前提p为素数

这里已经检验过x,y均为素数,而且他们相互特别接近。已经成功推理过了。这里不再赘述。

实现代码

import libnum
def decrypt(A,B):#A>B
    ans=1
    temp=pow(-1,1,A)
    for i in range(B+1,A):
        ans=(ans*libnum.invmod(i,A))%A
    return (ans*temp)%A
#decrypt(x,y) return的结果即为(math.factorial(y)) % x

7、欧拉函数求解

这里对应求get_q,欧拉函数
a ϕ ( m ) ≡ 1   ( m o d   m ) a^{\phi(m)}\equiv 1 \ (mod \ m ) aϕ(m)1 (mod m)

ϕ ( m ) = { m − 1 , m 为素数 m ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) ( 1 − 1 p 3 ) . . . m = p 1 a 1 p 2 a 2 p 3 a 3 . . . \phi(m)=\begin{cases} m-1, & {m为素数} \\ m(1- \frac{1}{p_1} )(1- \frac{1}{p_2})(1- \frac{1}{p_3})...& {m = p{_1}{^{a_1}}p{_2}{^{a_2}}p{_3}{^{a_3}}...} \end{cases} ϕ(m)={m1,m(1p11)(1p21)(1p31)...m为素数m=p1a1p2a2p3a3...

p都是素数,整理后可以是以下形式
ϕ ( m ) = ( p 1 − 1 ) ( p 2 − 1 ) ( p 3 − 1 ) ( p 4 − 1 ) . . . . m = p 1 ∗ p 2 ∗ p 3 . . . . \phi(m)=(p_1-1)(p_2-1)(p_3-1)(p_4-1).... \\m=p_1*p_2*p_3.... ϕ(m)=(p11)(p21)(p31)(p41)....m=p1p2p3....
一般就是q,p(即2个),多素数分解情况下可以为以上表示。

8、一次同余式求解

即求解
a x ≡ b   ( m o d   m ) ax\equiv b\ (mod\ m) axb (mod m)

转换后,给出公式
x ≡ b a ϕ ( m ) − 1 ( m o d   m ) x\equiv ba^{\phi(m)-1}(mod \ m) xbaϕ(m)1(mod m)

9、最终解体脚本

import libnum
import math
import sympy
from Crypto.Util.number import *
e = 65537
def decrypt(A,B):#A>B
    ans=1
    temp=pow(-1,1,A)
    for i in range(B+1,A):
        ans=(ans*libnum.invmod(i,A))%A
    return (ans*temp)%A

value=[80096058210213458444437404275177554701604739094679033012396452382975889905967]
for i in range(1, 10):
    value.append(sympy.prevprime(value[i - 1]))
n=1
for i in range(10):
    n = n * value[i]
fn=1
for i in range(10):
    fn = fn * (value[i]-1)
value_q = 5591130088089053683141520294620171646179623062803708281023766040254675625012293743465254007970358536660934858789388093688621793201658889399155357407224541324547522479617669812322262372851929223461622559971534394847970366311206823328200747893961649255426063204482192349202005330622561575868946656570678176047822163692259375233925446556338917358118222905050574458037965803154233167594946713038301249145097770337253930655681648299249481985768272321820718607757023350742647019762122572886601905212830744868048802864679734428398229280780215896045509020793530842541217790352661324630048261329493088812057300480085895399922301827190211956061083460036781018660201163819104150988531352228650991733072010425499238731811243310625701946882701082178190402011133439065106720309788819
d = libnum.invmod(e, fn)
q = pow(value_q, d, n)
q = sympy.nextprime(q)
x = 11124440021748127159092076861405454814981575144744508857178576572929321435002942998531420985771090167262256877805902135304112271641074498386662361391760451
y = 11124440021748127159092076861405454814981575144744508857178576572929321435002942998531420985771090167262256877805902135304112271641074498386662361391661439
p = decrypt(x,y)
p = sympy.nextprime(p)
n = p * q
c = 110644875422336073350488613774418819991169603750711465190260581119043921549811353108399064284589038384540018965816137286856268590507418636799746759551009749004176545414118128330198437101472882906564195341277423007542422286760940374859966152871273887950174522820162832774361714668826122465471705166574184367478
d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n)   # m 的十进制形式
string = long_to_bytes(m)  # m明文
print(string)  # 结果为 b‘ m ’ 的形式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Steins;G4te

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值