攻防世界题解随缘更新

一、Crypto

1.RSA

        1.1. 初识RSA

'''题目信息'''

from Crypto.Util.number import bytes_to_long,inverse,getPrime
from flag import flag

m = bytes_to_long(flag)

p = getPrime(1024)
q = getPrime(1024)
n = p*q
print(n)
e = 65537

c = pow(m,e,n)

pq = p*(q-1)
qp = q*(p-1)

print("c=",c)
print("n=",n)
print("pq=",pq)
print("qp=",qp)

'''
c= 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246
'''

        题目其实很简单,复习一下RSA的算法原理就清楚了。如果想要详细了解或者说学习、复习RSA的计算原理的可以参考RSA加密解密原理_rsa解密-CSDN博客,个人认为这篇博客对RSA的原理阐述非常清晰。

        对于一次RSA加解密,步骤一般为:

        1.随机生成两个质数p和q;

        2.计算n=p*q;

        3.计算欧拉函数z=(p-1)*(q-1);

        4.计算公钥e,其实是取值,1<e<z,要求e的取值必须是整数且e和z必须是互质数;

        5.根据公钥e和欧拉函数z计算私钥d,有d*e%z=1;

        6.根据以下等式进行加解密过程:

            C = M ^ e % n    #加密过程

            M = C ^ d % n    #解密过程

        但是一般的简单RSA题目都是明文(即为flag)缺失的,解题时就要逆着想,由已知的结果条件向上溯源,一般就会发现私钥d缺失。

'''参数说明:C为密文,M为明文,e为公钥,d为私钥,z为欧拉函数计算结果'''

    C = M ^ e % n    #加密过程

    M = C ^ d % n    #解密过程

    d * e % z = 1    #私钥d和公钥e的关系

    z = (p-1) * (q-1)    #z的计算方法

        解题过程也很简单,如下:

'''解题过程'''
from Crypto.Util.number import *

c = 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246
e = 65537

z = pq*qp//n
d = inverse(e, z)
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)

        简单查了一下,函数inverse(e,z)的作用就是:d*e%z=1,已知e和z,用来求d的,貌似是求得最小正整数。

if sys.version_info[:2] >= (3, 8):

    def inverse(u, v):    '''3.8版本及以上'''
        """The inverse of :data:`u` *mod* :data:`v`."""

        if v == 0:
            raise ZeroDivisionError("Modulus cannot be zero")
        if v < 0:
            raise ValueError("Modulus cannot be negative")

        return pow(u, -1, v)

else:

    def inverse(u, v):    '''3.8版本以下'''
        """The inverse of :data:`u` *mod* :data:`v`."""

        if v == 0:
            raise ZeroDivisionError("Modulus cannot be zero")
        if v < 0:
            raise ValueError("Modulus cannot be negative")

        u3, v3 = u, v
        u1, v1 = 1, 0
        while v3 > 0:
            q = u3 // v3
            u1, v1 = v1, u1 - v1*q
            u3, v3 = v3, u3 - v3*q
        if u3 != 1:
            raise ValueError("No inverse value can be computed")
        while u1<0:
            u1 = u1 + v
        return u1

        在Python3.8及以上的版本,inverse()函数的实现方式为pow(e,-1,z),而pow指数为-1时所代表的含义如下图:

        而在3.8以下的版本,inverse()函数可以照常使用,只不过如同代码所示,是由完全的数学计算实现的,并没有调用其它方法。

        1.2 baigeiRSA(白给)

'''题目信息'''
import libnum
from Crypto.Util import number
from secret import flag

size = 128
e = 65537
p = number.getPrime(size)
q = number.getPrime(size)
n = p*q

m = libnum.s2n(flag)
c = pow(m, e, n)

print('n = %d' % n)
print('c = %d' % c)

        有了上一题的经验,做这题就更是得心应手、如鱼得水了。发现缺少了p、q的信息,但是给出了n的值,经过搜索,可以使用yafu工具来对n进行因式分解,得到p和q。

'''解题过程'''
import libnum
from Crypto.Util.number import *

n = 88503001447845031603457048661635807319447136634748350130947825183012205093541
c = 40876621398366534035989065383910105526025410999058860023908252093679681817257
p = 274539690398523616505159415195049044439
q = 322368694010594584041053487661458382819
e = 65537

z = (p-1)*(q-1)
d = inverse(e, z)
m = pow(c, d, n)
flag = libnum.n2s(m)
print(flag)

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值