• 领航杯2022年-Crypto-rsa


    题目:

    1. #!/usr/bin/env python
    2. # -*- coding: utf-8 -*-
    3. from Crypto.Util.number import getPrime, bytes_to_long
    4. from secret import flag
    5. import gmpy2
    6. m = bytes_to_long(flag)
    7. p1 = getPrime(256)
    8. p2 = gmpy2.next_prime(p1)
    9. q1 = getPrime(256)
    10. q2 = gmpy2.next_prime(q1)
    11. n = p1*p2*q1*q2
    12. e = 65537
    13. c = pow(m, e, n)
    14. print "n = %s" % str(n)
    15. print "c = %s" % str(c)
    16. # n = 64167976067579049714960625453369319623574147507612434283986049223337768780480307767872484679214997588434480836733456745370562072077109044069294552424055163225824033286416753073591864962033181307822913035174676405849974928866646899569297852568167037383571518655075260561571463850326020102574832776970253538663
    17. # c = 61862798948167945139222097835309318688214053098609025632041946354708220281670731577734398373186075525909035569024535800893559811995294302363408878574730352951360726686941143742759917076156204564133401228995322937563878389120770732315714920284214472911769619065607001763986611359218449802649142381309774537696

    利用费马定理,分解2组素数:

    首先列出一个式子:n=p*q,代换到上面提到的p=a-b,q=a+b,那么就是n=(a-b)*(a+b),可以发现其实就是n=a*a-b*b,而b2不就是b的平方吗,所以有n=a*a-b2

    a的值在整个爆破过程中是从小到大的,相应的,b的值也是从小到大的,因为b*b=a*a-n,随着a的增大,b也会变大,而与之相应的,两个解:a-ba+b,之间的差距也会变大,而在最开始爆破的时候我们可以认为b=0,此时的a*a相当于在0~n之间求解的最‘中间’,这样我们就可以明白了,这个脚本正是从n的平方根这个‘中间值’开始,逐渐向两边扫描,直到得到解或者a-b==0,所以原理上它可以爆破出所有解

    这个脚本其实是一个爆破脚本,它会尝试每一种可能性,直到得到解,所以这个脚本也只能在初始值和解相近的时候使用

    好处就在于,这个脚本是一个爆破脚本,所以它能爆破出所有可能的解。

    在本题中,n由4个质数因子组成,其中两个成对近似相等。

    1. p1*q1, p2*q2非常相近
    2. p1*q2, p2*q1非常相近
    3. n = (p1*q1)*(p2*q2) = (p1*q2)*(p2*q1)
    4. 在sqrt(n) 这个‘中间值’两侧可以暴力破解出p1*q1, p2*q2,p1*q2, p2*q1等4个因子,进一步求出p1,p2, q1, q2。

    exp:

    1. from Crypto.Util.number import *
    2. from gmpy2 import *
    3. n = 64167976067579049714960625453369319623574147507612434283986049223337768780480307767872484679214997588434480836733456745370562072077109044069294552424055163225824033286416753073591864962033181307822913035174676405849974928866646899569297852568167037383571518655075260561571463850326020102574832776970253538663
    4. c = 61862798948167945139222097835309318688214053098609025632041946354708220281670731577734398373186075525909035569024535800893559811995294302363408878574730352951360726686941143742759917076156204564133401228995322937563878389120770732315714920284214472911769619065607001763986611359218449802649142381309774537696
    5. e = 65537
    6. def fermat_factorization(n):
    7. factor_list = []
    8. a,f = iroot(n,2)
    9. while(True):
    10. a += 1
    11. try:
    12. b,f = iroot(a*a - n, 2)
    13. except:
    14. pass
    15. if f: # b*b == a*a - n
    16. factor_list.append([a-b,a+b])
    17. if len(factor_list) == 2:
    18. break
    19. return factor_list
    20. factor_list = fermat_factorization(n)
    21. [p1q1,p2q2] = factor_list[0]
    22. [p1q2,p2q1] = factor_list[1]
    23. assert( p1q1*p2q2 == n)
    24. assert( p1q2*p2q1 == n)
    25. p1 = GCD(p1q1,p1q2)
    26. p2 = GCD(p2q1,p2q2)
    27. q1 = GCD(p1q1,p2q1)
    28. q2 = GCD(p1q2,p2q2)
    29. assert(isPrime(p1))
    30. assert(isPrime(p2))
    31. assert(isPrime(q1))
    32. assert(isPrime(q2))
    33. assert(p1*q1*p2*q2==n)
    34. phi = (p1 - 1) * (q1 - 1) * (p2 - 1) * (q2 - 1)
    35. d = inverse(e, phi)
    36. flag = pow(c, d, n)
    37. print(long_to_bytes(flag).decode())
    38. # CnHongKe{195a65b1-daa8-4786-b4f8-ca9e29d8804d}

  • 相关阅读:
    [架构之路-248]:目标系统 - 设计方法 - 软件工程 - 需求工程- 需求开发:如何用图形表达需求,结构化需求分析与面向对象需求分析的比较与融合
    不存在类型变量 A, T 的实例,使 Collector<T, A, List<T>> 符合 Supplier<R>
    vue路由传参刷新丢失
    docker搭建个人镜像仓库
    【Verilog】HDLBits题解——Verification: Reading Simulations
    上周热点回顾(10.24-10.30)
    【分享】“抖店“在集简云平台集成应用的常见问题与解决方案
    第3章业务功能开发(线索关联市场活动,动态搜索)
    golang[ssa & callgraph] 获取调用图实战
    mimikatz抓取密码实战
  • 原文地址:https://blog.csdn.net/rickliuxiao/article/details/126682839