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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM