RSA的共模攻击

实验吧题目:http://www.shiyanbar.com/ctf/1834

参考:http://hebin.me/2017/09/07/%e8%a5%bf%e6%99%aectf-strength/

首先说一下RSA的工作原理,RSA涉及一下几个参数:

  • 要加密的信息为m,加密后的信息为c;
  • 模n,负责计算出两个质数p和q,p和q计算欧拉函数值φ(n);
  • 欧拉函数值φ(n),φ(n)=(p-1)(q-1);
  • 公钥参数e和私钥参数d,可由欧拉函数值计算出,ed≡1 (mod φ(n));
  • 加密:me ≡ c (mod n)
  • 解密:cd ≡ m (mod n)

当n不变的情况下,知道n,e1,e2,c1,c2 可以在不知道d1,d2的情况下,解出m。

首先假设,e1,e2互质

gcd(e1,e2)=1

此时则有

e1*s1+e2*s2 = 1

式中,s1、s2皆为整数,但是一正一负。

通过扩展欧几里德算法,我们可以得到该式子的一组解(s1,s2),假设s1为正数,s2为负数.

因为

c1 = m^e1%n c2 = m^e2%n

所以

(c1^s1*c2^s2)%n = ((m^e1%n)^s1*(m^e2%n)^s2)%n

根据模运算性质,可以化简为

(c1^s1*c2^s2)%n = ((m^e1)^s1*(m^e2)^s2)%n

(c1^s1*c2^s2)%n = (m^(e1^s1+e2^s2))%n

又前面提到

e1*s1+e2*s2 = 1

所以

(c1^s1*c2^s2)%n = (m^(1))%n 
(c1^s1*c2^s2)%n = m^%n

c1^s1*c2^s2 = m

# 找出互质的两个e

# -*- coding: utf-8 -*-

from libnum import n2s,s2n
from gmpy2 import invert
# 欧几里得算法
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 main():
  n = 116547141139745534253172934123407786743246513874292261984447028928003798881819567221547298751255790928878194794155722543477883428672342894945552668904410126460402501558930911637857436926624838677630868157884406020858164140754510239986466552869866296144106255873879659676368694043769795604582888907403261286211
  c1 = 78552378607874335972488545767374401332953345586323262531477516680347117293352843468592985447836452620945707838830990843415342047337735534418287912723395148814463617627398248738969202758950481027762126608368555442533803610260859075919831387641824493902538796161102236794716963153162784732179636344267189394853
  c2 = 98790462909782651815146615208104450165337326951856608832305081731255876886710141821823912122797166057063387122774480296375186739026132806230834774921466445172852604926204802577270611302881214045975455878277660638731607530487289267225666045742782663867519468766276566912954519691795540730313772338991769270201
  e1 = 1804229351
  e2 = 17249876309
  s = egcd(e1, e2)
  s1 = s[1]
  s2 = s[2]
  # 求模反元素
  if s1<0:
    s1 = - s1
    c1 = invert(c1, n)
  elif s2<0:
    s2 = - s2
    c2 = invert(c2, n)

  m = pow(c1,s1,n)*pow(c2,s2,n) % n
  print n2s(m)

if __name__ == '__main__':
  main()

 

m = c1^s1*c2^s2 mod N

e1=1804229351

e2=17249876309

找到e1*s1+e2*s2=1的数(s1和s2异号)

s1=-49585666

s2=30337985

m = c1^s1*c2^s2 mod N

而在数论模运算中,要求一个数的负数次幂,与常规方法并不一样。

比如此处要求c2的s2次幂,就要先计算c2的模反元素c2r,然后求c2r的-s2次幂

找到s1的模反元素s1’=59221997946241237795280012961437755364319177847020996196260345560126624777905328671070619808742865206317231208856631213568682080308815472681816780528704149634900198556309885979020516076840693722669944415333783759008733319693789770248367473172650278434329453755225555333827588704035092685296296296058289109176

求m得到:m=11859814987468385682904193929732856121563109146807186957694593421160017639466355

posted on 2017-12-09 23:32  gwind  阅读(10231)  评论(0编辑  收藏

导航