crypto_RSA_gmpy2 新手题

题目

import libnum
import gmpy2
import uuid
import math

flag = "flag{" + str(uuid.uuid4()) + "}"
m = libnum.s2n(flag)
p = libnum.generate_prime(1024)
q = gmpy2.next_prime(p)
n = p * q
e = 65537
c = pow(m, e, n)

n = 12627644643778588563638920097915399454513514338804142285365906525498881036764131263143503359846189659273574532609463345820199502529021505655249992763681092637840409087205147095497477412031460598408163901210084467516709264700724398765301043908384308244747517893224665577128486689416162459250095126318456522046726204794830519283112518017007468770465828497144764208737754275011224549145753948172880930824906241704072415618131966725150546352452195727712056875106693907690990407658130836472884891082069644890044024145259903993177177196801509187283280149791400422260709944706691099262186583269852628892867781015062638406807
e = 65537
c = 3591154430994525075059034292233285219547469362782194889629270181283842636528606554393490851841066761509914849524082427752928544931823147005056532710833510595339404286404496491815089547021604266428940702481584786412593056050015881926826382036205406303525545716475450640777471292475111436226636460600345957363695624982558394414290121846251722500596533341384706714159205414604934501768918663557451374023537565102442827170460775303421150229829840660742855663501969208548706192593969737261023358057081741247088819534013372830024084918363322257487890942468889177188305118367719047889896681307253995123323963920988776643105

初见思路

翻译代码

将各个函数进行百度、谷歌明白其大致用法和含义。

uuid.uuid4 : 基于随机数,通过随机数来生成UUID. 使用的是伪随机数有一定的重复概率. 
libnum.s2n:字符串转十进制数
libnum.generate_prime(n):产生长度为n位的伪质数。 
gmpy2.next_prime(p):取p的下一个质数
pow(a,b,c):a^b mod c

搜索过程中,会发现代码实现的是RSA加密算法。
翻译完成后,再次回到题目,可得:

c = pow(m, e, n) 可表示为
m ^ e = n * ( m ^ e // n)  + c
^  表示阶乘
// 表示整除

然后就没有然后, m ^ e // n 是一个其大无比的数,难以爆破求解,且难以保证爆破结果一定准确。于是,G了。

RSA思路

基础概念

RSA加密算法是一种非对称加密算法,在公开密钥加密和电子商业中被广泛使用。
质数:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
公钥和私钥:是通过一种算法得到的一个密钥对(即一个公钥和一个私钥),其中的一个向外界公开,称为公钥;另个自己保留,称为私钥。
明文:是指没有加密的文字(或者字符串),一般人都能看懂。
密文:经过加密的文字。

数学原理

具体可见:https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
反正我没看懂,但从解题角度来读,我们只需要关心RSA加密算法如何加密和如何解密,无需知道其背后的数学原理。

实例

来源于 https://www.bilibili.com/video/BV1XP4y1A7Ui

加解密过程

在这里插入图片描述

此时,我们无需关心公钥是什么,私钥是什么,7,3,33这些数字代表什么含义,只需要知道通过这样的计算,我们可以将3,1,15加密为9,1,27,再解密为3,1,15。然后再思考:7,3,33是怎么来的?

公钥、私钥的制作过程

在这里插入图片描述
此时,我们无需知道为什么要这样计算公钥与私钥(也就是其数学原理),只需要知道公钥和私钥是这样子来的(你这样做就行了,干就完啦),在拥有公钥和私钥的情况我们可以进行加解密。

抽象化

通过以上例子,我们简单了解了RSA加密算法的运行过程。
将其概括一下,则为以下步骤:
1.选取两个质数 P , Q
2.计算N = P * Q
3.计算T = ( P - 1 ) * ( Q - 1 )
4.选择满足条件的公钥E:为质数 ; 1 < E < T ; 不是 T 的因子
5.计算满足条件的私钥D:(D * E)% T = 1
6.加密明文M获得密文C: C = M ^ E % N
7.解密密文C活得明文M: M = C ^ D % N

由此可见,RSA加密算法的关键是:最初选取的两个质数,掌握了这两个质数就可以根据公钥完成对私钥的破解,进而还原加解密过程.

解题

import libnum
import gmpy2
import uuid
import math

flag = "flag{" + str(uuid.uuid4()) + "}"
m = libnum.s2n(flag)
p = libnum.generate_prime(1024)
q = gmpy2.next_prime(p)
n = p * q
e = 65537
c = pow(m, e, n)

uuid.uuid4 : 基于随机数,通过随机数来生成UUID. 使用的是伪随机数有一定的重复概率. 
libnum.s2n:字符串转十进制数
libnum.generate_prime(n):产生长度为n位的伪质数。 
gmpy2.next_prime(p):取p的下一个质数
pow(a,b,c):a^b mod c

回到题目,对照之前概括的步骤可知:
m:明文
p、q:选取的两个质数,且q由gmpy2.next_prime§生成,即这两个质数存在一定的特征,在这里表现为,p是q的下一个质数。
n:n = p * q
e:公钥
c:密文

题目已知条件:
n = 12627644643778588563638920097915399454513514338804142285365906525498881036764131263143503359846189659273574532609463345820199502529021505655249992763681092637840409087205147095497477412031460598408163901210084467516709264700724398765301043908384308244747517893224665577128486689416162459250095126318456522046726204794830519283112518017007468770465828497144764208737754275011224549145753948172880930824906241704072415618131966725150546352452195727712056875106693907690990407658130836472884891082069644890044024145259903993177177196801509187283280149791400422260709944706691099262186583269852628892867781015062638406807
e = 65537
c = 3591154430994525075059034292233285219547469362782194889629270181283842636528606554393490851841066761509914849524082427752928544931823147005056532710833510595339404286404496491815089547021604266428940702481584786412593056050015881926826382036205406303525545716475450640777471292475111436226636460600345957363695624982558394414290121846251722500596533341384706714159205414604934501768918663557451374023537565102442827170460775303421150229829840660742855663501969208548706192593969737261023358057081741247088819534013372830024084918363322257487890942468889177188305118367719047889896681307253995123323963920988776643105
求明文m。

参照之前步骤,明文通过公钥加密得到密文,密文通过私钥还原得到明文。此处欲求明文,还需知道私钥。欲求私钥,还需要知道最初的两个质数。n = p * q。
我们将n进行因数分解。
此处使用网站http://factordb.com/进行因数分解。
在这里插入图片描述
点击show会显示具体数字。
在这里插入图片描述

点击蓝色数字会跳转到显示该数字的页面,然后再点该页面的show就可以看到这个具体数字了。
在这里插入图片描述

根据网站结果得:
p = 112372793165332455233644051831703093065233917285171435667727396467617869514267375433546885241603527682450490525106056020927668059639131922631965832681267028908272712604839741417231722918220018271377173404939261706593582911881852334650278053606220270970895872789340580971511712537114765669110273199402053062671
q = 112372793165332455233644051831703093065233917285171435667727396467617869514267375433546885241603527682450490525106056020927668059639131922631965832681267028908272712604839741417231722918220018271377173404939261706593582911881852334650278053606220270970895872789340580971511712537114765669110273199402053063417
计算私钥:(私钥 * 公钥)% (( p - 1 )*( q - 1 )) = 1,公钥:65537 (题目已知)
计算明文: 明文 = 密文 ^ 私钥 % ( p * q)

具体代码如下:

import libnum
import gmpy2
import uuid
import math
c = 3591154430994525075059034292233285219547469362782194889629270181283842636528606554393490851841066761509914849524082427752928544931823147005056532710833510595339404286404496491815089547021604266428940702481584786412593056050015881926826382036205406303525545716475450640777471292475111436226636460600345957363695624982558394414290121846251722500596533341384706714159205414604934501768918663557451374023537565102442827170460775303421150229829840660742855663501969208548706192593969737261023358057081741247088819534013372830024084918363322257487890942468889177188305118367719047889896681307253995123323963920988776643105
p = 112372793165332455233644051831703093065233917285171435667727396467617869514267375433546885241603527682450490525106056020927668059639131922631965832681267028908272712604839741417231722918220018271377173404939261706593582911881852334650278053606220270970895872789340580971511712537114765669110273199402053062671
q = 112372793165332455233644051831703093065233917285171435667727396467617869514267375433546885241603527682450490525106056020927668059639131922631965832681267028908272712604839741417231722918220018271377173404939261706593582911881852334650278053606220270970895872789340580971511712537114765669110273199402053063417
e = 65537
t = (p - 1) * (q - 1)
n = p * q
d = gmpy2.invert(e, t)  #取模逆,求私钥
m = pow(c, d, n)
print("m=", m)
flag = libnum.n2s(int(m))  # m = libnum.s2n(flag) 反一下
print("flag=", flag)

结果

m= 13040004482819480426069770791163535648582913834270310755786461965781344257500231259227632765
flag= b'flag{01d80670b01b654fe4831a3e81870734}'

完成!!!!!

思考

此题p,q有next_prime生成,存在一定的特征。若抹去该特征,因数分解难度将上升。

gmpy2的安装

https://pypi.org/project/gmpy2/#files此网站仅提供了python3.11版本及以下的安装文件
python3.12版本可前往https://github.com/aleaxit/gmpy/releases选择Release gmpy2 2.2.0a2进行下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值