任务六:RSA的代码实现

任务六:Crypto学习

内容:

① 学习RSA,掌握原理及代码实现。
② 完成题目:2020国赛初赛bd,完成WP



RSA

一、基本信息:
① RSA加密算法是一种非对称加密算法,属于公钥密码体系。广泛运用于许多场合。
② 为了提高RSA加密的保密强度,密钥长度至少为500位长,一般推荐使用1024位,在重要场合使用2048位。
二、算法说明:
① 随机选择两个不相等的质数p和q。(两个质数越大,月难以破解)
② 计算两个质数的乘积。(n = p×q,n的二进制位数就是RSA密钥的位数)
③ 计算n的欧拉函数。(φ(n) = (p-1)(q-1))
④ 随机选择一个整数e,是公钥中用来加密的数字。(要求:1<e<φ(n)且e与φ(n)互质)
⑤ 计算e相对于φ(n)的模乘反元素d。((e*d)mod φ(n) ≡ 1)
⑥ 将n和e封装成公钥,n和d封装成私钥。
三,攻击方法:
RSA算法利用乘方运算,明文以分组为单位进行加密,每个分组的二进制均小于n。收发双方均已知n发送方已知e,只有接收方已知d,公钥为{e,n},私钥为{d,n}。该算法主要用于公钥密码加密。
① 穷举攻击法:穷举出所有的可能的私钥
② 数字攻击法:使用数学定理来攻击的方法,实质都是试图分解出两个素数的乘积。
③ 选择密文攻击:利用RSA的性质进行攻击。

题目复现

先看题目

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

m = bytes_to_long(flag)

p = getPrime(512)
q = getPrime(512)
N = p * q
phi = (p-1) * (q-1)
while True:
    d = getRandomNBitInteger(200)
    if GCD(d, phi) == 1:
        e = inverse(d, phi)
        break

c = pow(m, e, N)

print(c, e, N, sep='\n')

# 37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
# 46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
# 86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289

从题目可知p和q是系统随机生成的大的随机素数,N为p与q的乘积,phi是N的欧拉函数,d是1到200内的一个随机数,且满足与phi互素的要求,e是d与phi的模乘反函数((e*d) mod phi ==1),c=m^e mod N。题目最后三行大数字分别是c,e,N输出的值。

解题代码如下:

import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
from Crypto.Util.number import long_to_bytes

def hack_RSA(e,n):
    '''
    Finds d knowing (e,n)
    applying the Wiener continued fraction attack
    '''
    frac = ContinuedFractions.rational_to_contfrac(e, n)  
    convergents = ContinuedFractions.convergents_from_contfrac(frac)
    
    for (k,d) in convergents:
        
        #check if d is actually the key
        if k!=0 and (e*d-1)%k == 0:

            phi = (e*d-1)//k
            s = n - phi + 1
            # check if the equation x^2 - s*x + n = 0
            # has integer roots
            discr = s*s - 4*n
            if(discr>=0):
                t = Arithmetic.is_perfect_square(discr)
                if t!=-1 and (s+t)%2==0:
                    print("Hacked!")
                    return d

# TEST functions

if __name__ == "__main__":
    n=86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289
    e=46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
    d=hack_RSA(e,n)
    print(d)
    c=37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
    m=pow(c,d,n)
    print(m)
    
flag=long_to_bytes(m)
print(flag)

注意要装库:pip install pycryptodome,并且将其中的n,e,c改为题目中的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值