BUUCTF 每日打卡 2021-5-21

博主讲述了期末考试期间解码一个看似十六进制但实为RSA加密的文本文件过程,通过计算gcd和lcm找到密钥,揭示了加密算法背后的数学原理。最终成功解码出NPUCTF{difficult_rsa_1s_easy}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

还有一个月就要期末考了,摸了摸了(
周末还要组织校赛,考四级口语,事情老多了

BASE

题目给了一个 22.8MB 的 txt 文件,里面都是数字和大写字母
看着好像就是普通的十六进制啊
结果尝试直接转十进制看看有没有头绪, 结果程序半天不出结果。。。
看着也不像 base64 啊
wp
直接暴力尝试 base16,base32,base64。。。
代码如下:

import base64
file = open("flag_encode.txt",'r')
file2 = open("flag",'w') 
base = file.read()
while(1):
    try:
        base = base64.b32decode(base).decode()
    except:
        try:
            base = base64.b64decode(base).decode()
        except:
            try:
                base = base64.b16decode(base).decode()
            except:
                print("解码完毕qwq!")
                file2.write(base)
                break

结果为:afctf{U_5h0u1d_Us3_T00l5}

EzRSA

加密代码如下:

from gmpy2 import lcm , powmod
from Crypto.Util.number import getPrime

p = getPrime(1024)
q = getPrime(1024)
n = p * q
gift = lcm(p - 1 , q - 1)
e = 54722
flag = b'NPUCTF{******************}'
m = int.from_bytes(flag , 'big')
c = powmod(m , e , n)
print('n: ' , n)
print('gift: ' , gift)
print('c: ' , c)

#n:  17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
#gift:  2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
#c:  3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319

题目给了 lcm(p - 1 , q - 1) p − 1 p-1 p1 q − 1 q-1 q1 的最小公倍数),又因为
l c m ( p − 1 , q − 1 ) = ( p − 1 ) ∗ ( q − 1 ) g c d ( p − 1 , q − 1 ) lcm(p-1,q-1) = \frac{(p-1)*(q-1)}{gcd(p-1,q-1)} lcm(p1,q1)=gcd(p1,q1)(p1)(q1)
所以
φ = ( p − 1 ) ∗ ( q − 1 ) = g c d ( p − 1 , q − 1 ) ∗ l c m ( p − 1 , q − 1 ) \varphi = (p-1)*(q-1) = gcd(p-1,q-1) * lcm(p-1,q-1) φ=(p1)(q1)=gcd(p1,q1)lcm(p1,q1)
又因为 n = p ∗ q n=p*q n=pq , p , q p, q p,q 均为大质数,所以有 n ≈ φ n\approx \varphi nφ

g c d ( p − 1 , q − 1 ) ≈ n l c m ( p − 1 , q − 1 ) = n g i f t gcd(p-1,q-1)\approx \frac{n}{lcm(p-1,q-1)} = \frac{n}{gift} gcd(p1,q1)lcm(p1,q1)n=giftn
代码如下:

n = 17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
gift = 2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
c = 3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319
e = 54722

print(n//gift)

得到结果 g c d ( p − 1 , q − 1 ) ≈ 8 gcd(p-1,q-1)\approx 8 gcd(p1,q1)8
另一个奇怪的地方就是 e = 54722 e = 54722 e=54722 φ \varphi φ 不互质,与原来的 RSA 加密算法不同
我们令 e ′ = e / / 2 e'=e//2 e=e//2 因为 e ′ e' e φ \varphi φ互质
所以有 e ∗ d ≡ 1   m o d   φ e*d \equiv 1 \space mod \space \varphi ed1 mod φ
故有 d ′ = 2 ∗ d   s . t .   e ′ ∗ d ′ = e ∗ d ≡ 1   m o d   n d'=2*d\space s.t.\space e'*d' = e*d \equiv 1 \space mod \space n d=2d s.t. ed=ed1 mod n
m ′ ≡ c d ′   m o d   n = c 2 d   m o d   n m' \equiv c^{d'} \space mod \space n = c^{2d} \space mod \space n mcd mod n=c2d mod n
所以 m ≡ m ′   m o d   n m \equiv \sqrt{m'} \space mod \space n mm  mod n
完整代码如下:

from Crypto.Util.number import *
from gmpy2 import gcd, iroot

n = 17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
gift = 2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
c = 3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319
e = 54722

phi = gift * (n//gift)
e = e//2
d = inverse(e, phi)
m = pow(c, d, n)
m = iroot(m, 2)[0]
print(long_to_bytes(m))

结果为:NPUCTF{diff1cult_rsa_1s_e@sy}

结语

不知不觉这个学期算上今天已经更了 47 篇了
总算把前三面刷完了,快要把 1 分题刷穿了
这学期就到这了
希望继续坚持吧

<think>好的,我现在要帮助用户理解互质的概念以及相关的算法实现。首先,我需要回顾一下互质的定义和常见算法。 根据引用[2],互质指的是两个整数的最大公约数(GCD)为1。也就是说,如果GCD(a, b) == 1,那么a和b互质。另外,互质的另一种等价定义是它们的约数集合的交集只有1。这帮助我确认了基本定义。 接下来,用户可能想知道如何判断两个数是否互质。常见的算法是欧几里得算法,用于计算最大公约数。例如,引用[4]中的Python代码展示了如何用欧几里得算法寻找与f互质的整数e。如果GCD为1,则两数互质。这提示我应该详细解释欧几里得算法的步骤,并给出代码示例。 用户提供的引用[1]和[3]也提到了用最大公约数判断互质的方法。例如,引用[1]中的Java实现和引用[3]中的C语言方法都是通过遍历可能的公约数来判断。不过,欧几里得算法更高效,尤其是在处理大数时,时间复杂度更低,所以应该优先介绍这种方法。 我需要考虑用户可能的疑问,例如互质的不同应用场景,比如密码学中的RSA算法(如引用[4]中的数字签名),或者数学问题中的质数分解。同时,用户可能需要了解如何实现算法,所以提供代码示例会很有帮助。 另外,用户可能对算法的优化感兴趣。比如,在引用[3]中提到的遍历到较小的数为止,但欧几里得算法可以更快地计算GCD,不需要遍历所有可能的因数。因此,比较不同方法的效率也是一个要点。 最后,需要确保回答结构清晰,分步骤解释互质的概念、判断方法、算法实现(如欧几里得算法)以及应用场景。同时,生成的相关问题要覆盖定义、算法实现、优化和应用等方面,帮助用户进一步探索。</think>### 互质的定义与算法实现 #### 一、互质的定义 两个整数$a$和$b$(不同时为0)称为**互质**(或**互素**),当且仅当它们的最大公约数(GCD)等于1,即: $$ \gcd(a, b) = 1 $$ 等价定义:两数的约数集合的交集仅包含1[^2]。 #### 二、判断互质的核心算法 1. **计算最大公约数(GCD)** 使用**欧几里得算法**(辗转相除法),通过递归或迭代计算两数的GCD: - 若$a > b$,则$\gcd(a, b) = \gcd(b, a \mod b)$ - 重复直到余数为0,此时非零余数即为GCD - 若最终结果为1,则两数互质[^4]。 2. **Python实现示例** ```python def gcd(a, b): while b != 0: a, b = b, a % b return a def are_coprime(a, b): return gcd(abs(a), abs(b)) == 1 # 示例:判断8和15是否互质 print(are_coprime(8, 15)) # 输出True ``` #### 三、算法优化与应用 - **时间复杂度**:欧几里得算法的时间复杂度为$O(\log \min(a, b))$,远优于暴力枚举法($O(n)$)。 - **应用场景**: - 密码学:如RSA算法中生成公钥和私钥时需选择互质的整数; - 数学问题:简化分数$\frac{a}{b}$时需保证分子分母互质; - 数论研究:如中国剩余定理中要求模数互质[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值