【密码学】破解RSA密码(Python代码实现)

题目👇

已知有人写了如下的代码,并将生成的(n,e,c)以及(n2,e2,c2,(p2+1)*(q2+1))输出。

from Crypto.Util.number import *

def ef():
    p=getPrime(512)
    q=getPrime(512)
    flag=open("flag","rb").read()
    m=bytes_to_long(flag)
    e=65537
    n=p*q
    c=pow(m,e,n)
    print(n,e,c)  #
    return p,q

def epq(p,q):
    p2=getPrime(1024)
    q2=getPrime(1024)
    e2=65537
    m2=p+q
    n2=p2*q2
    c2=pow(m2,e2,n2)
    print(n2,e2,c2,(p2+1)*(q2+1)) #

p,q=ef()
epq(p,q)

输出(n,e,c)以及(n2,e2,c2,(p2+1)*(q2+1))如下:

(86902041785171683231305301154659574124170175717542478743469937094129588097899526472297338165763793395403138052107436307148655516237914989260641272558370267587581870375426597336633068656306063961150434589742092844368242428011721324737315708847899038491875643600715933822290329122093126146305056053635875427149L, 65537, 15833685544860151615528563318175057334854555807563811248911092184962045410721043935895279999715546874344448072757248024629816018687138160349497178202841685747385455984597261139196670787723191129190281464722284764818569442853999503305719960273532581788705319675785365330814771611391805600982635624166616994909L)

(18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828433745751900636977114625384201443358493405946175157229330447527380345317933922535718700042422977893867943656666930789561406630888405895439054817890293649823406983304364531032464229623788486039136673884818993067818472490283937605836580590843487927803181532325018537076264511576862025094690559279649143498659102849L, 65537, 7392251042794448813724942265095985628606500546061544026052413736090062985580390082556940969813307099293888028876436850564855740297176392396726998769680589219160575972891500463789856128741737806143813567755324525667951325489807002065570746854557547784519649141813876707420713784143969266692484619922991587339418980913573323306950701125825931923149350170489304772562424051072424741158162269063304635895188390600892069271483630208193319815348033784877031408074730563809389105637498825225265591866481815230255385046830196748192233124781928655809322769875744414705189416861877961926362356094198048709542228727393696757158L, 18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828434020648157035533967661393926860975983001244775722594600595802713222548261077015534360904269663877978505992018966625264663179236777522008665977063509158288897299644184441313228368572324485490486359818154230942787018240908451883098571389138398322839231059197174670650732257722735400365023996558029601185819826736L)

请编写代码,求出flag。

思路分析👇

首先要搞清楚RSA的加密解密原理,其算法过程如下:

由用户选择两个互异并且距离较远的大素数p和q

计算n=p×qφn)=(p-1)×(q-1)

选择正整数e,使其与f(n)的最大公约数为1;

然后计算正整数d,使得e×d 对f(n)的余数为1,即e×d≡1 mod φ(n)最后销毁p和q

经过以上步骤,得出公钥对(n,e)和私钥对(n,d)。

设M为明文,C为对应的密文,

则加密变换为:C=M^e mod n

解密变换为:M=C^d mod n

题目中设有两层RSA加密

第一次加密是用公钥e=65537对明文flag加密,这一步是肯定要有的,但是我们不知道p和q具体是多少,求出φ(n)=(p-1)×(q-1)是很困难的,暴力破解1000多位的RSA花费时间不可估计,所以题目给了一些提示,这便是第二次加密的原因。

第二次加密是用公钥e=65537对第一次加密中的私钥p和q之和加密,加密的原理还是基本的RSA,不同的是虽然第二次加密用的新随机生成的私钥p2和q2,但是题目还额外给出了(p2+1)×(q2+1)这个信息,这便是突破口。

所以解题的方法就是递推回去,先解开第二层RSA加密,得到第一层加密中使用的私钥对之和p+q,再继续解第一层加密,最后得到结果flag。

①先解第二层加密👇

第二层加密给出了n2,e2,c2,(p2+1)×(q2+1)这四个参数,因为n2=p2×q2,简单推导我们可以得到

φ(n2)=(p2-1)×(q2-1)=p2×q2-p2-q2+1=2×p2×q2-(p2×q2+p2+q2+1)+2

根据扩展欧几里得算出公钥e=65537模φ(n2)的逆inv2,然后直接将c2和inv2模n2运算即可得到第二层加密的明文p+q的值。

②解第一层加密👇

第二层加密给出了n,e,c这三个参数,因为n=p×q,简单推导我们可以得到

φ(n)=(p-1)×(q-1)=p×q-p-q+1=p×q-(p+q)+1

根据扩展欧几里得算出公钥e=65537模φ(n)的逆inv,然后直接将c和inv模n运算即可得到第一层加密的明文flag的字节值。

最后的字节值别忘了使用long_to_bytes()转换成最后的明文flag

代码示例👇

①对思路分析中的猜想进行验证测试👇

#coding:utf-8
#author:Mitchell
#date:12.24
from Crypto.Util.number import *

#欧几里得求最大公因子
def gcd(a, b):
    while a != 0:
        a, b = b % a, a
    return b

#扩展欧几里得求模逆
def exgcd(a, m):
    if gcd(a, m) != 1:
        return None
    u1,u2,u3 = 1, 0, a
    v1,v2,v3 = 0, 1, m
    while v3 != 0:
        q = u3 // v3#地板除
        v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
    return u1 % m

#模拟第一层加密
def ef():
    p=getPrime(512)
    q=getPrime(512)
    flag=b'Legends never die!'
    print('falg=',flag)
    m=bytes_to_long(flag)
    print('m=',m)
    e=65537
    n=p*q
    c=pow(m,e,n)
    return p,q,(n,e,c)  #

#模拟第二层加密
def epq(p,q):
    p2=getPrime(1024)
    q2=getPrime(1024)
    e2=65537
    m2=p+q
    print('m2=',m2)
    n2=p2*q2
    c2=pow(m2,e2,n2) 
    return (n2,e2,c2,(p2+1)*(q2+1)) #

#模拟参数生成,这里的p和q仅仅用于参数生成,按规则不能直接查看
p,q,A=ef()
B=epq(p,q)
#求得φ(n2)=(p2-1)×(q2-1)=p2×q2-p2-q2+1=2×p2×q2-(p2×q2+p2+q2+1)+2
phi2=B[0]*2-B[3]+2
#使用扩展欧几里得求出inv2
inv2=exgcd(B[1],phi2)
#第二层解密
m2=pow(B[2],inv2,B[0])
print('解密解得m2=',m2)
#求得φ(n)=(p-1)×(q-1)=p×q-p-q+1=p×q-(p+q)+1
phi=A[0]-m2+1
#使用扩展欧几里得求出inv
inv=exgcd(A[1],phi)
#第一层解密
m=pow(A[2],inv,A[0])
print('解密解得m=',m)
#转码得到flag
flag=long_to_bytes(m)
print('解密解得flag=',flag)

②实操破解题目中的RSA👇

#coding:utf-8
#author:Mitchell
#date:12.24
from Crypto.Util.number import *

'''已知有人写了如下的代码,并将生成的(n,e,c)以及(n2,e2,c2,(p2+1)*(q2+1))输出。
def ef():
    p=getPrime(512)
    q=getPrime(512)
    flag=open("flag","rb").read()
    m=bytes_to_long(flag)
    e=65537
    n=p*q
    c=pow(m,e,n)
    print(n,e,c)  #
    return p,q

def epq(p,q):
    p2=getPrime(1024)
    q2=getPrime(1024)
    e2=65537
    m2=p+q
    n2=p2*q2
    c2=pow(m2,e2,n2) 
    print(n2,e2,c2,(p2+1)*(q2+1)) #

p,q=ef()
epq(p,q)

输出(n,e,c)以及(n2,e2,c2,(p2+1)*(q2+1))如下:

(86902041785171683231305301154659574124170175717542478743469937094129588097899526472297338165763793395403138052107436307148655516237914989260641272558370267587581870375426597336633068656306063961150434589742092844368242428011721324737315708847899038491875643600715933822290329122093126146305056053635875427149L, 65537, 15833685544860151615528563318175057334854555807563811248911092184962045410721043935895279999715546874344448072757248024629816018687138160349497178202841685747385455984597261139196670787723191129190281464722284764818569442853999503305719960273532581788705319675785365330814771611391805600982635624166616994909L)

(18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828433745751900636977114625384201443358493405946175157229330447527380345317933922535718700042422977893867943656666930789561406630888405895439054817890293649823406983304364531032464229623788486039136673884818993067818472490283937605836580590843487927803181532325018537076264511576862025094690559279649143498659102849L, 
65537, 
7392251042794448813724942265095985628606500546061544026052413736090062985580390082556940969813307099293888028876436850564855740297176392396726998769680589219160575972891500463789856128741737806143813567755324525667951325489807002065570746854557547784519649141813876707420713784143969266692484619922991587339418980913573323306950701125825931923149350170489304772562424051072424741158162269063304635895188390600892069271483630208193319815348033784877031408074730563809389105637498825225265591866481815230255385046830196748192233124781928655809322769875744414705189416861877961926362356094198048709542228727393696757158L, 
18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828434020648157035533967661393926860975983001244775722594600595802713222548261077015534360904269663877978505992018966625264663179236777522008665977063509158288897299644184441313228368572324485490486359818154230942787018240908451883098571389138398322839231059197174670650732257722735400365023996558029601185819826736L)

请编写代码,求出flag。'''

#欧几里得求最大公因子
def gcd(a, b):
    while a != 0:
        a, b = b % a, a
    return b

#扩展欧几里得求模逆
def exgcd(a, m):
    if gcd(a, m) != 1:
        return None
    u1,u2,u3 = 1, 0, a
    v1,v2,v3 = 0, 1, m
    while v3 != 0:
        q = u3 // v3#地板除
        v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
    return u1 % m

A=(86902041785171683231305301154659574124170175717542478743469937094129588097899526472297338165763793395403138052107436307148655516237914989260641272558370267587581870375426597336633068656306063961150434589742092844368242428011721324737315708847899038491875643600715933822290329122093126146305056053635875427149, 65537, 15833685544860151615528563318175057334854555807563811248911092184962045410721043935895279999715546874344448072757248024629816018687138160349497178202841685747385455984597261139196670787723191129190281464722284764818569442853999503305719960273532581788705319675785365330814771611391805600982635624166616994909)

B=(18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828433745751900636977114625384201443358493405946175157229330447527380345317933922535718700042422977893867943656666930789561406630888405895439054817890293649823406983304364531032464229623788486039136673884818993067818472490283937605836580590843487927803181532325018537076264511576862025094690559279649143498659102849, 
65537, 
7392251042794448813724942265095985628606500546061544026052413736090062985580390082556940969813307099293888028876436850564855740297176392396726998769680589219160575972891500463789856128741737806143813567755324525667951325489807002065570746854557547784519649141813876707420713784143969266692484619922991587339418980913573323306950701125825931923149350170489304772562424051072424741158162269063304635895188390600892069271483630208193319815348033784877031408074730563809389105637498825225265591866481815230255385046830196748192233124781928655809322769875744414705189416861877961926362356094198048709542228727393696757158, 
18591274039015146371355461783271676729436253989312203484465267365829253730222536917260636899143825565341750487371058728119621305795504534209590790135844600724302582139316981344931079461283380928221091934542959757790517904211220170283310587231962911318192160954877212603169707693638590690557518269614342828434020648157035533967661393926860975983001244775722594600595802713222548261077015534360904269663877978505992018966625264663179236777522008665977063509158288897299644184441313228368572324485490486359818154230942787018240908451883098571389138398322839231059197174670650732257722735400365023996558029601185819826736)

#求得φ(n2)=(p2-1)×(q2-1)=p2×q2-p2-q2+1=2×p2×q2-(p2×q2+p2+q2+1)+2
phi2=B[0]*2-B[3]+2
#使用扩展欧几里得求出inv2
inv2=exgcd(B[1],phi2)
#第二层解密
m2=pow(B[2],inv2,B[0])
print('解密解得m2=',m2)
#求得φ(n)=(p-1)×(q-1)=p×q-p-q+1=p×q-(p+q)+1
phi=A[0]-m2+1
#使用扩展欧几里得求出inv
inv=exgcd(A[1],phi)
#第一层解密
m=pow(A[2],inv,A[0])
print('解密解得m=',m)
#转码得到flag
flag=long_to_bytes(m)
print('解密解得flag=',flag)

运行效果👇

①测试结果👇

②实操效果👇

最终的flag为flag{3101231231231231c421cccccc},这个熟悉的格式,爷青回!

  • 15
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
以下是RSA算法的代码实现,包括密钥生成、加密和解密三个部分。 首先是密钥生成部分: ```python import random from math import gcd # 生成密钥 def generate_key(p, q): n = p * q phi = (p-1) * (q-1) # 找到一个合适的e,满足1 < e < phi(n)且gcd(e, phi(n)) = 1 e = random.randrange(1, phi) g = gcd(e, phi) while g != 1: e = random.randrange(1, phi) g = gcd(e, phi) # 计算d,使得d与e满足ed ≡ 1 (mod phi(n)) d = mod_inverse(e, phi) # 返回公钥和私钥 return ((e, n), (d, n)) # 扩展欧几里得算法计算模反元素 def mod_inverse(a, m): if gcd(a, m) != 1: return None u1, u2, u3 = 1, 0, a v1, v2, v3 = 0, 1, m while v3 != 0: q = u3 // v3 v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3 return u1 % m ``` 接下来是加密和解密部分: ```python # RSA加密 def encrypt(plaintext, public_key): e, n = public_key ciphertext = [pow(ord(char), e, n) for char in plaintext] return ciphertext # RSA解密 def decrypt(ciphertext, private_key): d, n = private_key plaintext = [chr(pow(char, d, n)) for char in ciphertext] return ''.join(plaintext) ``` 使用示例: ```python # 生成密钥 p = 17 q = 19 public_key, private_key = generate_key(p, q) print("公钥:", public_key) print("私钥:", private_key) # 加密 plaintext = "Hello, world!" ciphertext = encrypt(plaintext, public_key) print("密文:", ciphertext) # 解密 plaintext = decrypt(ciphertext, private_key) print("明文:", plaintext) ``` 输出结果: ``` 公钥: (493, 323) 私钥: (269, 323) 密文: [94, 203, 267, 267, 126, 147, 267, 94, 126, 147, 94, 94, 10, 203, 147, 126, 267, 94, 10, 203, 94, 10, 232, 232] 明文: Hello, world! ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mitch311

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

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

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

打赏作者

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

抵扣说明:

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

余额充值