RSA攻击

最近觉得自己的密码学真的是采得一塌糊涂,要重新做人

从最基础的RSA开始吧,也参考了好多大佬的博客

http://www.freebuf.com/sectool/163781.html

https://www.anquanke.com/post/id/84632

https://blog.csdn.net/kevin66654/article/details/53898465

https://blog.csdn.net/veritas501/article/details/55257957

RSA加密基本原理

选择两个大素数p和q,计算出模数N = p * q

计算φ = (p−1) * (q−1) 即N的欧拉函数,然后选择一个e (1<e<φ),且e和φ互质

取e的模反数为d,计算方法: e * d ≡ 1 (mod φ)

对明文A进行加密:B≡A^e (mod N) 或 B = pow(A,e,N),得到的B即为密文

对密文B进行解密,A≡B^d( mod N) 或 A = pow(B,d,N),得到的A即为明文

大家一般性用python的pow函数的时候只用两个参数,这里三个参数是不一样的用法,算是昨晚次方运算后对n取模

p 和 q :大整数N的两个因子(factor)

N:大整数N,我们称之为模数(modulus)

e 和 d:互为模反数的两个指数(exponent)

c 和 m:分别是密文和明文,这里一般指的是一个十进制的数

一般有如下称呼:

(N,e):公钥

(N,d):私钥

模数分解

关键就是把大数N分解为两个素数p,q,只要能分解出来,一切都好说

假设我们分解除了p,q,则φ已知

我们已知e * d ≡ 1 (mod φ),那么在已知e与φ的情况下,就可以直接求出私钥d

怎么求解呢,为了再次加深理解,我又去翻了翻信安数学基础----一次同余式求解

若要这个方程有解,首先要满足gcd(e,φ)=1       #gcd:求两个数的最大公约数,

def gcd(a, b):   #求最大公约数
    if a < b:
        a, b = b, a
    while b != 0:
        temp = a % b
        a = b
        b = temp
    return a

当然在CTF中这一步大部分情况可以省略,如果不符合这个也没法攻击

接下来采取迭代来使用广义Euclid求出是否有符合的整数x,y

def egcd(a, b):                       #egcd:求满足ax+by=1,当gcd(a,b)=1时,满足式子的x和y
    if a == 0:
      return (b, 0, 1)
    else:
      g, y, x = egcd(b % a, a)
      return (g, x - (b // a) * y, y)
  def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
      raise Exception('modular inverse does not exist')
    else:
      return x % m

若以上条件不成立,则无法求出私钥d

知道密钥之后,直接解密就好了:m=pow(c,d,N)            #c表示密文,m表示明文

分解大素数N以及别的一些攻击方式

有时候题目不会给我们p,q,而是直接给我们大素数N,需要我们自己来分解

1. 如果n在768bit或者更高,可以尝试使用一些在线的n分解网站,这些网站会存储一些已经分解成功的n,

比如:http://factordb.com

这个网站成功率还是蛮高的

2. 有时候会遇到一种题目,就是采用的公钥e都相同,但是两个加密的大素数N都不同,经常让人一头雾水,这种情况下,这些大素数N会有相同的素数因子,那我们直接求公约数就好了,求出公约数后,就可以把另一个素数因子也求出来

def gcd(a, b):
   if a < b:
     a, b = b, a
   while b != 0:
     temp = a % b
     a = b
     b = temp
   return a

3. 还遇见过一种情况,公钥e特别小

比如e=3,你对明文m加密,m^3显然比大素数N小许多,那直接对密文c开三次方就完事了

或者说三次方之后就比N大一点点,那我们假设他们相差的值为k,我们不断爆破k开三次方就行

i=0
   while 1:
   if(gmpy.root(c+i*N, 3)[1]==1):
     print gmpy.root(c+i*N, 3)
     break
   i=i+1

4. 共模攻击

如果在RSA的使用中使用了相同的模N对相同的明文m进行了加密,那么就可以在不分解n的情况下还原出明文m的值,说白就是取得e不一样

def egcd(a, b):
    if a == 0:
      return (b, 0, 1)
    else:
      g, y, x = egcd(b % a, a)
      return (g, x - (b // a) * y, y)
  def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
      raise Exception('modular inverse does not exist')
    else:
      return x % m

s = egcd(e1, e2)
 s1 = s[1]
 s2 = s[2]
   print s
 n=n1
   if s1<0:
     s1 = - s1
     c1 = modinv(c1, n)
   elif s2<0:
     s2 = - s2
     c2 = modinv(c2, n)
 m=(pow(c1,s1,n)*pow(c2,s2,n)) % n

5. 只要p和q存在相差过大或者过近时,都可以通过yafu很快地分解成功

openssl

有些题目提供enc和pem文件,这个时候就是Linux下的工具openssl登场的时候了

openssl 语句
从公钥中读取e和n:openssl rsa -pubin -text -modulus -in warmup -in 【public.pem】
Rsatool.py生成指定的私钥:python rsatool.py -o 【private.pem】 -e 【65537】 -p 【123】-q 【123】
用私钥解密:openssl rsautl -decrypt -in 【flag.enc】 -inkey 【private.pem】 

这我也不知道该怎么说,拿个例题吧

Medium RSA------Jarvis OJ

下载下来是个压缩包,打开一看两个文件

然后跑出公钥

接着直接用http://factordb.com分解大素数N得到p,q

然后生成私钥d,需要rsatool,给个链接:https://blog.csdn.net/veritas501/article/details/55257957

最后再用openssl解密

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值