首页 > 其他分享 >RSA加解密实战(CTF)

RSA加解密实战(CTF)

时间:2024-11-12 12:17:13浏览次数:3  
标签:公钥 加密 pt 加解密 RSA 解密 CTF ct

这个实战题目来源于我参加的某海外CTF比赛原题,由于这个题目相较于一般的 RSA 加密方式有些许差别,个人感觉比较有趣且不难懂,于是拿来分享。

对于 RSA 加密的基本认识

一、什么是 RSA 加密算法

        RSA 加密是一种非对称加密方式,使用2种密钥分别对数据进行加解密:

                a、公钥:用于数据的加密,可以公开共享

                b、私钥:用于数据的解密,需要妥善保管,不能泄露

        公钥只能用于加密数据,私钥只能用于解密数据,二者不可更换使用,即用公钥加密的数据只能使用对应的私钥进行解密,反之亦然。

二、RSA 加密的数学基础

        RSA算法的核心是大数运算模运算,基于数论中的一些性质:

                a、大素数的生成:选择两个大素数 p 和 q

                b、模数 n 的计算: n=p×q

                c、欧拉函数 φ(n): φ(n)=(p−1)×(q−1)

                d、选择加密指数 e: e 与 φ(n) 互质,通常选择 e=65537,可以带来较好的计算效率

                e、计算解密指数 d:d 是 e 关于 φ(n) 的模逆元素,即满足 e⋅d≡1 mod  φ(n)

三、密钥生成步骤

        1、选择两个大素数 p 和 q,计算 n=p×q

        2、计算 φ(n)=(p−1)×(q−1) 

        3、选择一个整数 e,满足 1<e<φ(n)且 gcd(e,φ(n))=1

        4、计算 e 的模逆 d,即 e⋅d≡1mod  φ(n)

        5、公钥为 (n,e),私钥为 (n,d)

四、加密过程

要加密的明文消息 m 转换为整数 m 且 0≤m<n,加密得到的密文 c 计算如下:

五、解密过程

接收到密文 ccc 后,解密计算如下:

题目分享与解析

首先题目的线索是直接给了一个关于 RSA 密钥生成和加解密的 python 源码,需要对这串代码进行简要分析:

# getPrime用于生成指定位数的质数
# bytes_to_long 用于将字节序列转化为长整型数字
# long_to_bytes 用于将长整型数字转化为字节序列
# FLAG_GAMGAM 定义在 flag 模块中的常量,通常时需要加密的字符串
from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes
from flags import FLAG_GAMGAM

#生成密钥
def gen_key():
    p = getPrime(4096)   #生成一个4096位的大素数
    n = 2*p         #公钥的模数n
    e = 65537       #常用公钥指数e=65535
    #一般来说RSA的模数是两个大素数的乘积 n = p * q , 根据欧拉函数可得 φ(n) = φ(p) * φ(q) = (p-1)*(q-1),又因为n=2p,所以 φ(n) = p-1
    phi_n = (p - 1)  
    #计算私钥指数d
    d = pow(e, -1, phi_n)

	#返回公钥和私钥
    return (n, e), (n, d)

#定义加密函数,接收整型明文 pt 和公钥,并返回一个加密后的整型密文
def encrypt(pt: int, pub_key: (int, int)) -> int:
    n, e = pub_key
    return pow(pt, e, n)


#定义解密函数,接收整型密文 ct 和私钥,并返回一个解密后的整型明文
def decrypt(ct: int, priv_key: (int, int)) -> int:
    n, d = priv_key
    return pow(ct, d, n)


#转化明文,方便后续的 RSA 加密
pt = bytes_to_long(FLAG_GAMGAM)
#生成公钥和私钥
pub, priv = gen_key()

#加密得到密文
ct = encrypt(pt, pub)

print(pub)  #输出公钥(n,e)
print(ct)   #输出密文 ct

""" output : 
pub = (1187036881143255678002463758823328059054967286304079946698830107983054756455116137560640360907617090768892222200232769013898086641365526920365941657223719909608623612364565491394396836689005779953582737606769612044152900984410189797945160970640233269434857215156707188226644140186233117418578999649675501923158500973527860820476774162258056088176836933971626651722297419469001832141393303687831763041541298637984981484605886538085054999743028130034186150375954369138007688335922353720290223733062752735362640330007395278113210621407774253326748367183647916542260385241849328645829055161868897760626313462053770486741600871918596910274170809764858924373557759944088849747488101309508664734646761762412297919300985341470183672896494363089287897564003884864937477882116184866139314943820121458541671053111784924614354354051278861337795171453392846554516472806170955424094756390970572454084554064299959563385403753982420758416150497980281277588694172034437436874006653172021381177623273333042379989422646166480734410913148567193586525237775287519085811109666011917375279015787726665088346364963313941503929463975682736763812440239892582271133388552728034109040233071519106207594592661468817905961569517921007110971395505830618097714478302, 65537)
ct = 795807804195143453698199351714341881491007858193124317249991960343873442402330541927355975462857321435938754440321580174443331666641181625664069405050964566344381744709294110771870536802353007022271867378658681771017152652337537847752445300535171488167996282441962543976576696465573991060306807268553659109840313328518099780850408480656440234846473549017585724141302898515099966486748289860601838615696366759534875502563433987281076478746704673766615604679732113066945172837918782569635525478298453073137252252807049842035005266808708242245205256476149494296039430508531375107451338401537609064664390446408507706477965483671800993119312002909135270398571898844908643483215653937390863031730605961379386046951618745731912613235578147115643378764728145934422515365821994913473759604466504627671738552946527189180057717976411101700962342930065732023681381389942592202841123754672836935980227561011259880242223658584675417448037977336301973044247690228389495603711704632306639520856078639797104835378636642939190389932673963835980987694812947833691746134338765367684261289851826492260573430796933048931658801423183863572727478714738535956082504958502080116828296338104460121704114347331800007862970894127699814246457589160922514051314061
"""

一、对于“phi_n = (p - 1)”的补充说明

        1、欧拉函数φ(n)的定义
                欧拉函数 φ(n) 是指在小于 n 的正整数中,与 n 互质的数的个数

        2、欧拉函数性质
                a、若 n 为质数,那么φ(n)=n-1
                b、乘法性质:
                        若两个数 a、b 互质,则φ(a * b)=φ(a) * φ(b)

        根据上述定义和性质,可得:
        因为两个质数 p、q 一定互质,且 n=p*q
        所以 φ(n)=φ(p * q)=φ(p) * φ(q) = (p-1) * (q-1)


        因为n=2p 且2与p互质,所以 φ(n) = φ(2 * p) = φ(2) * φ(p)
        根据:
                a、φ(2)=1,因为小于 2 且与 2 互质的数只有 1
                b、φ(p)=p−1,因为 p 是素数,所有小于 p 的数都与 p 互质


        得出结论:
                φ(n) = φ(2) * φ(p) = 1*(p-1) = p-1

二、具体解析

        这个RSA加密的实现并没有使用传统的 n=p*q,而是利用 ”根据n=2p,使得 φ(n)=p-1” 这一公钥生成方式,这就是我开头说的 “与一般的 RSA 加密方式的些许差别 ”,即公钥的生成。

        根据以上的分析,整理解题思路:
                1、求解p:由于`n=2p`,因此`p=n/2`
                2、求解d:因为`p=n/2`,可以得到`φ(n)=p−1`,根据代码`d = pow(e, -1, phi_n)`,可以得到私钥指数d
                3、解密:得到 d 后,使用 RSA 解密公式 `pt=ct^d  mod  n`还原明文。
                4、回转字符串:最后,使用 `long_to_bytes(pt)` 将整数明文转换回原始 FLAG 的字符串形式

用于解密的python代码:
from Crypto.Util.number import long_to_bytes

# 已知的公钥 n 和密文 ct
n = 1187036881143255678002463758823328059054967286304079946698830107983054756455116137560640360907617090768892222200232769013898086641365526920365941657223719909608623612364565491394396836689005779953582737606769612044152900984410189797945160970640233269434857215156707188226644140186233117418578999649675501923158500973527860820476774162258056088176836933971626651722297419469001832141393303687831763041541298637984981484605886538085054999743028130034186150375954369138007688335922353720290223733062752735362640330007395278113210621407774253326748367183647916542260385241849328645829055161868897760626313462053770486741600871918596910274170809764858924373557759944088849747488101309508664734646761762412297919300985341470183672896494363089287897564003884864937477882116184866139314943820121458541671053111784924614354354051278861337795171453392846554516472806170955424094756390970572454084554064299959563385403753982420758416150497980281277588694172034437436874006653172021381177623273333042379989422646166480734410913148567193586525237775287519085811109666011917375279015787726665088346364963313941503929463975682736763812440239892582271133388552728034109040233071519106207594592661468817905961569517921007110971395505830618097714478302
e = 65537
ct = 795807804195143453698199351714341881491007858193124317249991960343873442402330541927355975462857321435938754440321580174443331666641181625664069405050964566344381744709294110771870536802353007022271867378658681771017152652337537847752445300535171488167996282441962543976576696465573991060306807268553659109840313328518099780850408480656440234846473549017585724141302898515099966486748289860601838615696366759534875502563433987281076478746704673766615604679732113066945172837918782569635525478298453073137252252807049842035005266808708242245205256476149494296039430508531375107451338401537609064664390446408507706477965483671800993119312002909135270398571898844908643483215653937390863031730605961379386046951618745731912613235578147115643378764728145934422515365821994913473759604466504627671738552946527189180057717976411101700962342930065732023681381389942592202841123754672836935980227561011259880242223658584675417448037977336301973044247690228389495603711704632306639520856078639797104835378636642939190389932673963835980987694812947833691746134338765367684261289851826492260573430796933048931658801423183863572727478714738535956082504958502080116828296338104460121704114347331800007862970894127699814246457589160922514051314061

# Step 1: 计算 p 和 phi_n
p = n // 2
phi_n = p - 1

# Step 2: 计算 d
d = pow(e, -1, phi_n)

# Step 3: 解密密文
pt = pow(ct, d, n)

# Step 4: 转换为字符串
flag = long_to_bytes(pt)
#根据要求的 flag 形式输出完整的flag
print(f"4T{{{flag.decode()}}}")

三、结果

        最后成功拿到 flag:

标签:公钥,加密,pt,加解密,RSA,解密,CTF,ct
From: https://blog.csdn.net/2301_81517733/article/details/143690142

相关文章

  • 一个简单的容器(CTF)
    这个是一个某海外CTF中的题目,给的提示比较明显,过程思路清晰,较于简单,容易理解。一、查看环境,制定大致思路首先创建实例后访问地址,发现是一个仿Linux终端的交互式shell环境,根据自己的做题经验,那我们的思路就大致是在Linux环境中查找类似于flag.txt的文件二、根据自己......
  • [GXYCTF2019]Ping Ping Ping
    打开页面如下:按提示输入ip127.0.0.1尝试加管道符,查看目录结构,?ip=127.0.0.1|lscat查看flag.php他骂我们,说空格不行。使用其他字符替换空格,?ip=127.0.0.1|cat$IFS$9flag.php又骂我们,说flag字符串不行,我们先看看index.php,直接审计代码看看怎么绕过,?ip=127.0.0.1|cat$IFS$......
  • [SUCTF 2019]EasySQL
    当输入数字时返回array结构,且任意非0数字都是返回1。当输入字符串时无任何回显。那么我们可以猜测sql语句中存在逻辑或符号||,因为任意非0在mysql中相当于true且返回值为1,而字符及字符串会被当作变量处理,或运算时会报错。那么绕过的方法是将mysql的sql_mode参数设置为PIPES_AS_CO......
  • [ACTF2020 新生赛]Exec
    打开页面如下:直接输入127.0.0.1,ping完没反应,猜测可能是命令执行,尝试使用管道符|,输入命令127.0.0.1|ls,有回显尝试往上查找目录,1270.0.1|ls../../../发现flag目录。直接使用cat命令查看,1270.0.1|cat../../../flag......
  • go实现AES加解密
    go实现是和之前我python和jsAES加解密的方式一样,可以相互解密。文件结构  encryption.gopackageencryptionimport("bytes""crypto/aes""crypto/cipher""crypto/sha256""encoding/base64""encoding/hex......
  • ACTF新生赛2020:swp
    好家伙流量分析启动一路看过来大部分是TCP请求,统计里看看HTTP的请求有一个秘密的压缩包下面还有个提示将HTTP流中的数据导出,查看一下刚刚那个hint.html提示不需要密码,不出意外的话和后面的压缩包有关系猜对咯是需要密码的,但是既然已经提示了不需要密码,那就应该是伪......
  • [ACTF2020 新生赛]Include
    发现flag.php就在这但是不回显结果。这时考虑使用伪协议间接读取源码内容以base64伪协议为例:payload为:?file=php://filter/convert.base64-encode/resource=index.php得到index.php的源码的base64编码形式,PG1ldGEgY2hhcnNldD0idXRmOCI+Cjw/cGhwCmVycm9yX3JlcG9ydGluZygwK......
  • [HCTF 2018]WarmUp
    打开页面只有一个表情包,F12查看网页代码有个提示,我们直接转到source.php页面发现还有一个hint.php,访问可以得到提示:通过审计代码发现,emmm实现了一个白名单功能,只有source和hint可以访问通过。下面的if检查$_REQUEST['file']是否存在且为字符串类型,并调用emmm::checkFile方法......
  • CTF学习24.11.7[日志分析和流量分析]
    MISC03日志分析和流量分析01日志分析什么是日志?Web访问日志记录了Web服务器接收处理请求及运行时错误等各种原始信息。通过对Web日志进行的安全分析,不仅可以帮助我们定位攻击者,还可以帮助我们还原攻击路径,找到网站存在的安全漏洞并进行修复。日志记录的内容计算机日志是......
  • [GXYCTF2019]BabySQli
    题目链接:[GXYCTF2019]BabySQli。个人认为这道题是脑洞题(当然也跟基础业务知识不够有关)。打开题目后环境如下。只有一个登录框,因此常规操作,先测试一下看看。通过多次输入不同的UserName、password发现,存在admin用户,并且可以遍历UserName。接下来尝试注入,发现似乎只有......