CTF竞赛之RSA非对称算法讲解——附(例题)

RSA算法要点总结

RSA 算法的可靠性由极大整数因数分解的难度决定。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠

1、公钥与私钥的产生:

(1)进行加密之前,首先找出2个不同的互质数 p 和 q

(2)计算 n = p*q

(3)根据欧拉函数,求得φ(n) = (p−1)(q−1)

(4)找出一个公钥e,e要满足: 1 < e < φ(n) 的整数,且使 e 和 φ(n) 互质。

(5)根据   (e*d) % φ(n) = 1  的方式, 找到私钥d。

(6)所以,公钥就是 e,私钥就是 d 。

2、加密和解密的过程:

加密:m^{e} % n = c

解密:c^{d} % n = m

m 为明文,c 为密文,公钥为 e,私钥为 d。

3、安全性——传播的过程:

传播信息:n、e、c

解密:n、d、c

e\overset{\phi (n)}{\rightarrow}d

φ(n)  = p * q,求φ(n)  即求p、q。即质数分解。

例题1:

题目:求出m,转换成二进制,即位flag
p+q : 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea
(p+1)(q+1) : 0x5248becef1d925d45705a7302700d6a0ffe5877fddf9451a9c1181c4d82365806085fd86fbaab08b6fc66a967b2566d743c626547203b34ea3fdb1bc06dd3bb765fd8b919e3bd2cb15bc175c9498f9d9a0e216c2dde64d81255fa4c05a1ee619fc1fc505285a239e7bc655ec6605d9693078b800ee80931a7a0c84f33c851740
e : 0xe6b1bee47bd63f615c7d0a43c529d219
d : 0x2dde7fbaed477f6d62838d55b0d0964868cf6efb2c282a5f13e6008ce7317a24cb57aec49ef0d738919f47cdcd9677cd52ac2293ec5938aa198f962678b5cd0da344453f521a69b2ac03647cdd8339f4e38cec452d54e60698833d67f9315c02ddaa4c79ebaa902c605d7bda32ce970541b2d9a17d62b52df813b2fb0c5ab1a5
enc_flag: 0x50ae00623211ba6089ddfae21e204ab616f6c9d294e913550af3d66e85d0c0693ed53ed55c46d8cca1d7c2ad44839030df26b70f22a8567171a759b76fe5f07b3c5a6ec89117ed0a36c0950956b9cde880c575737f779143f921d745ac3bb0e379c05d9a3cc6bf0bea8aa91e4d5e752c7eb46b2e023edbc07d24a7c460a34a9a
解题思路:
  • (p+1)*(q+1) = p*q + p+q + 1 = n + p+q + 1
  • n = (p+1)*(q+1) - (p+q + 1)
  • m = c^{d} % n 

解题代码:

from Crypto.Util.number import long_to_bytes

q = 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea
w = 0x5248becef1d925d45705a7302700d6a0ffe5877fddf9451a9c1181c4d82365806085fd86fbaab08b6fc66a967b2566d743c626547203b34ea3fdb1bc06dd3bb765fd8b919e3bd2cb15bc175c9498f9d9a0e216c2dde64d81255fa4c05a1ee619fc1fc505285a239e7bc655ec6605d9693078b800ee80931a7a0c84f33c851740
e = 0xe6b1bee47bd63f615c7d0a43c529d219
d = 0x2dde7fbaed477f6d62838d55b0d0964868cf6efb2c282a5f13e6008ce7317a24cb57aec49ef0d738919f47cdcd9677cd52ac2293ec5938aa198f962678b5cd0da344453f521a69b2ac03647cdd8339f4e38cec452d54e60698833d67f9315c02ddaa4c79ebaa902c605d7bda32ce970541b2d9a17d62b52df813b2fb0c5ab1a5
c = 0x50ae00623211ba6089ddfae21e204ab616f6c9d294e913550af3d66e85d0c0693ed53ed55c46d8cca1d7c2ad44839030df26b70f22a8567171a759b76fe5f07b3c5a6ec89117ed0a36c0950956b9cde880c575737f779143f921d745ac3bb0e379c05d9a3cc6bf0bea8aa91e4d5e752c7eb46b2e023edbc07d24a7c460a34a9a
n = w - q - 1
m = pow(c,d,n)
print(long_to_bytes(m) )

例题2:

简单的rsa - Bugku CTF平台

本题目得到的是一个pyc反编译文件,首先进入反编译网址进行反编译

python反编译 - 在线工具

得到代码:

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.9

import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex, b2a_hex
flag = '******************'
p = 0xED7FCFABD3C81C78E212323329DC1EE2BEB6945AB29AB51B9E3A2F9D8B0A22101E467
q = 0xAD85852F9964DA87880E48ADA5C4487480AA4023A4DE2C0321C170AD801C9
e = 65537
n = p * q
c = pow(int(b2a_hex(flag), 16), e, n)
print(c)
c = 0x75AB3202DE3E103B03C680F2BEBBD1EA689C8BF260963FE347B3533B99FB391F0A358FFAE5160D6DCB9FCD75CD3E46B2FE3CFFE9FA2E9508702FD6E4CE43486631
解题思路:
  • 题目已知,e、n、c,根据 (e*d) % φ(n) = 1 ,即可求出d
  • 求出d后,根据c^{d} % n = m,即可得到m,
  • 求出发现 是  b'ZmxhZ3tJbGlrZUNURmJ1dENURmRvbid0bGlrZW1lfQ=='
  • 根据经验得知这是base64的,然后进行base64解码即可

解题代码:


import base64
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex, b2a_hex
# flag = '******************'
p = int('0xED7FCFABD3C81C78E212323329DC1EE2BEB6945AB29AB51B9E3A2F9D8B0A22101E467',16)
q = int('0xAD85852F9964DA87880E48ADA5C4487480AA4023A4DE2C0321C170AD801C9',16)
e = 65537
phi = (p-1)*(q-1)
n = p * q
# c = pow(int(b2a_hex(flag), 16), e, n)
# print(c)
c = int('0x75AB3202DE3E103B03C680F2BEBBD1EA689C8BF260963FE347B3533B99FB391F0A358FFAE5160D6DCB9FCD75CD3E46B2FE3CFFE9FA2E9508702FD6E4CE43486631',16)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flags = long_to_bytes(m)
print(flags)
print(base64.b64decode(flags))

flag{IlikeCTFbutCTFdon'tlikeme}

例题3:

MaybeEasyRSA - Bugku CTF平台

 下载题目得到代码

from Crypto.Util.number import *
from secret import flag
from sympy import nextprime

flag=b''

r = getRandomNBitInteger(64)
p1 = r**5 + r**4 - r**3 + r**2 - r + 2024
q1 = r**5 - r**4 + r**3 - r**2 + r + 2024
p =nextprime(p1)
q =nextprime(q1)
n = p*q

def enc(flag, n):
    m = bytes_to_long(flag)
    return pow(m, 65537, n)


c = enc(flag, n)
print(n)
print(c)

#1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683
#643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569
解题思路:
  • 做RSA的题上来先读题,搜选已知条件,看题目给的代码可知,题目已给出了n,c,e=65537,同时题目给了n的计算方式,因此我们需要得到p、q来求解φ(n) ,因此就涉及到了分解n
  • 根据题目求解n的方式,同时结合数学中的思想可以得到,对p和q影响最大的是r的5次方,p*q = n,因此对n影响最大的即为n的10次方,因此我们可以率先对n进行开10次方根进行遍历,然后分解获取p和q的值,获取之后求得φ(n)即为phi
  • 根据 (e*d) % φ(n) = 1 ,即可求出d求出d后,根据c^{d} % n = m,即可得到m
  • 根据经验得知这是base64的,然后进行base64解码即可

 解题代码:

import gmpy2
from Crypto.Util.number import *
from sympy import nextprime

flag=b''
c = 643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569
n = 1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683
e = 65537
r_n = gmpy2.iroot(n , 10)[0]
for r in range(r_n-10 , r_n+10):
    p1 = r**5 + r**4 - r**3 + r**2 - r + 2024
    q1 = r**5 - r**4 + r**3 - r**2 + r + 2024
    p = nextprime(p1)
    q = nextprime(q1)
    if p*q == n:
       phi = (p - 1) * (q - 1)
       break;

d = gmpy2.invert(e,phi)

m = pow(c , d , n)
print(m)
print(long_to_bytes(m))
bugku{01a25ea3fd6349c6e635a1d0196e75fb}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小馨馨的小翟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值