RSA学习2 —— 公钥密码

本文读完需要20分钟

    • 小指数明文爆破 (small e & c)
    • 选择密文攻击 (can't decrypt c)
    • LLL-attack ( A reveal m )
    • Wiener attack (big e & small d)
    • Boneh Durfee attack
    • 共模攻击 (same n attack)
    • 广播攻击 (small e)
    • 相关m1、m2攻击
    • DSA

小指数明文爆破 (small e & c)

如果B使用的e很小,如e=3,且A传给B的明文也很小,如几个字节
那么,c = m^ e mod n 如果n很大 则可能 c = m^ e 即 c=m^ 3 即对c开三次根号
就可以得到m
如果m的三次方大于n但是没有超过太多
即 k*n 且k是可以爆破的大小

k*n - c = m^3

例题1、

n=47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e=3
c=10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839

RSA学习2 —— 公钥密码_第1张图片

from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime, isPrime
import primefac
def modinv(a, n):
    return primefac.modinv(a, n) % n
n = 47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e = 3
c = 10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839
import gmpy2
i = 0
while 1:
    if (gmpy2.iroot(c + i * n, 3)[1] == 1):
        print long_to_bytes(gmpy2.iroot(c + i * n, 3)[0])
        break
    i = i + 1

import gmpy2
gmpy2.mpz(n)#初始化一个大整数
gmpy2.mpfr(x)# 初始化一个高精度浮点数x
d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
C = gmpy2.powmod(M,e,n)# 幂取模,结果是 C = (M^e) mod n
gmpy2.is_prime(n) #素性检测
gmpy2.gcd(a,b) #欧几里得算法,最大公约数
gmpy2.gcdext(a,b) #扩展欧几里得算法
gmpy2.iroot(x,n) #x开n次根

选择密文攻击 (can’t decrypt c)

如果可以对任意密文解密
但不能对c解密
则使用选择密文攻击

首先求出c在n上的逆元 c^-1
再求 c^-1 的明文m ’ 为明文的逆元
再求逆

如果存在交互可以对任意密文进行解密,并获取1bit的话,则可以实现RSA parity oracle攻击

LLL-attack ( A reveal m )

如果B使用的e仍然是3,同时A在密文m前加了段说明,即密文的一部分已泄露
或者B泄露p或q的部分

可以通过Coppersmith method求得明文

例题2、

n=6605504825889906202615748618066615187648800018528841933516316527012434141085944518043517968365397208826746013914157780887914632131531725863903538584417200527430582588764927544641557369303652648618292067488950921453386626677080964591489000067415450844331150724748818976858613279276478837816955089131430026237158610099210296694041096318330028075396562522499372070896421812111982381954403594724817813599972527870269930328689605408419124792951097063104670279395547265345199330843872092262422909324703892472836919443820718316384657112213693649570846294917435669334446894791207245948586388312000876428472397897528075326181
e=3
base=0x9876543210fedcba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
m=base+x
c=509143472960679964712061323134017269675726146763840337342493411055818623664115844443674190631269444040761374004286322788918255893217259171816916764385142572139730607623044481570957838700886892396989322684261802615250176830520657672566986118693899055342488599895558649859959818014882032199503639959456476815874298279286366688505291464700166422158955162203921387290954912301297909167283802751188777341587497155942072022517346786613010384892896362040794853435381349

目前,GitHub上提供了进行LLLattack的sage代码 参考Git 脚本
使用sage-online sagemath
在这里插入图片描述
选择CoCalc 注册账号 sign in ,然后 create new project
RSA学习2 —— 公钥密码_第2张图片

import time
debug = True

# display matrix picture with 0 and X
def matrix_overview(BB, bound):
    for ii in range(BB.dimensions()[0]):
        a = ('%02d ' % ii)
        for jj in range(BB.dimensions()[1]):
            a += '0' if BB[ii,jj] == 0 else 'X'
            a += ' '
        if BB[ii, ii] >= bound:
            a += '~'
        print a

def coppersmith_howgrave_univariate(pol, modulus, beta, mm, tt, XX):
    """
    Coppersmith revisited by Howgrave-Graham

    finds a solution if:
    * b|modulus, b >= modulus^beta , 0 < beta <= 1
    * |x| < XX
    """
    #
    # init
    #
    dd = pol.degree()
    nn = dd * mm + tt

    #
    # checks
    #
    if not 0 < beta <= 1:
        raise ValueError("beta should belongs in (0, 1]")

    if not pol.is_monic():
        raise ArithmeticError("Polynomial must be monic.")

    #
    # calculate bounds and display them
    #
    """
    * we want to find g(x) such that ||g(xX)|| <= b^m / sqrt(n)
    * we know LLL will give us a short vector v such that:
    ||v|| <= 2^((n - 1)/4) * det(L)^(1/n)
    * we will use that vector as a coefficient vector for our g(x)

    * so we want to satisfy:
    2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)

    so we can obtain ||v|| < N^(beta*m) / sqrt(n) <= b^m / sqrt(n)
    (it's important to use N because we might not know b)
    """
    if debug:
        # t optimized?
        print "\n# Optimized t?\n"
        print "we want X^(n-1) < N^(beta*m) so that each vector is helpful"
        cond1 = RR(XX^(nn-1))
        print "* X^(n-1) = ", cond1
        cond2 = pow(modulus, beta*mm)
        print "* N^(beta*m) = ", cond2
        print "* X^(n-1) < N^(beta*m) \n-> GOOD" if cond1 < cond2 else "* X^(n-1) >= N^(beta*m) \n-> NOT GOOD"

        # bound for X
        print "\n# X bound respected?\n"
        print "we want X <= N^(((2*beta*m)/(n-1)) - ((delta*m*(m+1))/(n*(n-1)))) / 2 = M"
        print "* X =", XX
        cond2 = RR(modulus^(((2*beta*mm)/(nn-1)) - ((dd*mm*(mm+1))/(nn*(nn-1)))) / 2)
        print "* M =", cond2
        print "* X <= M \n-> GOOD" if XX <= cond2 else "* X > M \n-> NOT GOOD"

        # solution possible?
        print "\n# Solutions possible?\n"
        detL = RR(modulus^(dd * mm * (mm + 1) / 2) * XX^(nn * (nn - 1) / 2))
        print "we can find a solution if 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)"
        cond1 = RR(2^((nn - 1)/4) * detL^(1/nn))
        print "* 2^((n - 1)/4) * det(L)^(1/n) = ", cond1
        cond2 = RR(modulus^(beta*mm) / sqrt(nn))
        print "* N^(beta*m) / sqrt(n) = ", cond2
        print "* 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n) \n-> SOLUTION WILL BE FOUND" if cond1 < cond2 else "* 2^((n - 1)/4) * det(L)^(1/n) >= N^(beta*m) / sqroot(n) \n-> NO SOLUTIONS MIGHT BE FOUND (but we never know)"

        # warning about X
        print "\n# Note that no solutions will be found _for sure_ if you don't respect:\n* |root| < X \n* b >= modulus^beta\n"
    #
    # Coppersmith revisited algo for univariate
    #

    # change ring of pol and x
    polZ = pol.change_ring(ZZ)
    x = polZ.parent().gen()

    # compute polynomials
    gg = []
    for ii in range(mm):
        for jj in range(dd):
            gg.append((x * XX)**jj * modulus**(mm - ii) * polZ(x * XX)**ii)
    for ii in range(tt):
        gg.append((x * XX)**ii * polZ(x * XX)**mm)

    # construct lattice B
    BB = Matrix(ZZ, nn)

    for ii in range(nn):
        for jj in range(ii+1):
            BB[ii, jj] = gg[ii][jj]

    # display basis matrix
    if debug:
        matrix_overview(BB, modulus^mm)

    # LLL
    BB = BB.LLL()

    # transform shortest vector in polynomial    
    new_pol = 0
    for ii in range(nn):
        new_pol += x**ii * BB[0, ii] / XX**ii

    # factor polynomial
    potential_roots = new_pol.roots()
    print "potential roots:", potential_roots

    # test roots
    roots = []
    for root in potential_roots:
        if root[0].is_integer():
            result = polZ(ZZ(root[0]))
            if gcd(modulus, result) >= modulus^beta:
                roots.append(ZZ(root[0]))

    return roots
length_N = 1024 # size of the modulus
Kbits = 120 # size of the root
e = 3
N=66055048258899062026157486180666151876488000185288419335163165270124341410859445180435179683653972088267460139141577808879146321315317258639035385844172005274305825887649275446415573693036526486182920674889509214533866266770809645914890000674154508443311507247488189768586132792764788378169550891314300262371586100992102966940410963183300280753965625224993720
708964218121119823819544035947248178135999725278702699303286896054084191247929510970631046702793955472653451993308438720922624229093247038924728369194438207183163846571122136936495
70846294917435669334446894791207245948586388312000876428472397897528075326181
ZmodN = Zmod(N);
C=509143472960679964712061323134017269675726146763840337342493411055818623664115844443674190631269444040761374004286322788918255893217259171816916764385142572139730607623044481570957838700886892396989322684261802615250176830520657672566986118693899055342488599895558649859959818014882032199503639959456476815874298279286366688505291464700166422158955162203921387290954912301297909167283802751188777341587497155942072022517346786613010384892896362040794853435381349
# Problem to equation (default)
P. = PolynomialRing(ZmodN) #, implementation='NTL')
base=0x9876543210fedcba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
pol = (2^length_N - 2^Kbits + x)^e - C
print 2^length_N
print 2^Kbits
print x
pol = (base - 2^Kbits + x)^e - C
dd = pol.degree()
# Tweak those
beta = 1 # b = N
epsilon = beta / 7 # <= beta / 7
mm = ceil(beta**2 / (dd * epsilon)) # optimized value
tt = floor(dd * mm * ((1/beta) - 1)) # optimized value
XX = ceil(N**((beta**2/dd) - epsilon)) # optimized value
# Coppersmith
start_time = time.time()
roots = coppersmith_howgrave_univariate(pol, N, beta, mm, tt, XX)
# output
print "\n# Solutions"
#print "we want to find:",str(K)
print "we found:", str(roots)
print("in: %s seconds " % (time.time() - start_time))
print "\n"

得到m=1861040492750592458109753184254913405
RSA学习2 —— 公钥密码_第3张图片

m=1861040492750592458109753184254913405
print long_to_bytes(m)

输出
RSA学习2 —— 公钥密码_第4张图片

Wiener attack (big e & small d)

如果B选择的e很大d很小
就是维纳攻击
参考Git 脚本

例题3、

n=13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
e=12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
c=2484709721197628568638797402073216500708160464312296481998154858152984191027965025447989735734511441378560655450049827280421394684794686868637129792025922467050637633861712489439050924034250791362044295391037523401336182117452300215045245450296408968446161318116489796932195251728012370464275380708222965034038535444718036607417409791819713679701286765333564430457444950590872952872847451701520252433653744766600366204445415719316381678856907782811329370712566969122411760039675147452944459447458029499649366966091750148097800564333924237813299417594128610382764223185901473523134684572326437208151512306054708160038

RSA学习2 —— 公钥密码_第5张图片

'''
Created on Dec 14, 2011

@author: pablocelayes
'''

import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
import sys
sys.setrecursionlimit(10000000)   #增加回溯的空间

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 = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227

    e =12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
    print hack_RSA(e, n)

RSA学习2 —— 公钥密码_第6张图片
这是d = 2355246239

n = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
c = 2484709721197628568638797402073216500708160464312296481998154858152984191027965025447989735734511441378560655450049827280421394684794686868637129792025922467050637633861712489439050924034250791362044295391037523401336182117452300215045245450296408968446161318116489796932195251728012370464275380708222965034038535444718036607417409791819713679701286765333564430457444950590872952872847451701520252433653744766600366204445415719316381678856907782811329370712566969122411760039675147452944459447458029499649366966091750148097800564333924237813299417594128610382764223185901473523134684572326437208151512306054708160038
d=2355246239
m=pow(c,d,n)

def num2str(num):
    tmp=hex(num)[2:].replace("L","")
    if len(tmp) % 2 == 0:
        return tmp.decode("hex")
    else:
        return ("0"+tmp).decode("hex")
print num2str(m)

RSA学习2 —— 公钥密码_第7张图片

Boneh Durfee attack

如果d没有足够小,则尝试Boneh Durfee attack进行攻击 ,参考Git的相关脚本

共模攻击 (same n attack)

B在两次通信中使用相同的n
A对相同的m加密

攻击者可以不计算d而直接算出m

例题4、

n1=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e1=65537
c1=11623242520063564721509699039034210329314238234068836130756457335142671659158578379060500554276831657322012285562047706736377103534543565179660863796496071187533860896148153856845638989384429658963134915230898572173720454271369543435708994457280819363318783413033774014447450648051500214508699056865320506104733203716242071136228269326451412159760818676814129428252523248822316633339393821052614033884661649376604245744651142959498917235138077366818109892738298251161767344501687113868331134288984466294415889635863660753717476594011236542159800099371872396181448655448842148998667568104710807411358117939831241620315
n2=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e2=70001
c2=8180690717251057689732022736872836938270075717486355807317876695012318283159440935866297644561407238807004565510263413544530421072353735781284166685919420305808123063907272925594909852212249704923889776430284878600408776341129645414000647100303326242514023325498519509077311907161849407990649396330146146728447312754091670139159346316264091798623764434932753276554781692238428057951593104821823029665203821775755835076337570281155689527215367647821372680421305939449511621244288104229290161484649056505784641486376741409443450331991557221540050574024894427139331416236263783977068315294198184169154352536388685040531
from Crypto.Util.number import long_to_bytes,bytes_to_long,getPrime,isPrime
import primefac
def same_n_attack(n,e1,e2,c1,c2):

    def egcd(a, b):
        x, lastX = 0, 1
        y, lastY = 1, 0
        while (b != 0):
            q = a // b   #整除
            a, b = b, a % b
            x, lastX = lastX - q * x, x
            y, lastY = lastY - q * y, y
        return (lastX, lastY)

    s = egcd(e1, e2)
    s1 = s[0]
    s2 = s[1]
    if s1<0:
        s1 = - s1
        c1 = primefac.modinv(c1, n)
        if c1<0:
            c1+=n
    elif s2<0:
        s2 = - s2
        c2 = primefac.modinv(c2, n)
        if c2<0:
            c2+=n
    m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
    return m
n1=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e1=65537
c1=11623242520063564721509699039034210329314238234068836130756457335142671659158578379060500554276831657322012285562047706736377103534543565179660863796496071187533860896148153856845638989384429658963134915230898572173720454271369543435708994457280819363318783413033774014447450648051500214508699056865320506104733203716242071136228269326451412159760818676814129428252523248822316633339393821052614033884661649376604245744651142959498917235138077366818109892738298251161767344501687113868331134288984466294415889635863660753717476594011236542159800099371872396181448655448842148998667568104710807411358117939831241620315
n2=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e2=70001
c2=8180690717251057689732022736872836938270075717486355807317876695012318283159440935866297644561407238807004565510263413544530421072353735781284166685919420305808123063907272925594909852212249704923889776430284878600408776341129645414000647100303326242514023325498519509077311907161849407990649396330146146728447312754091670139159346316264091798623764434932753276554781692238428057951593104821823029665203821775755835076337570281155689527215367647821372680421305939449511621244288104229290161484649056505784641486376741409443450331991557221540050574024894427139331416236263783977068315294198184169154352536388685040531
print long_to_bytes(same_n_attack(n1,e1,e2,c1,c2))

输出
RSA学习2 —— 公钥密码_第8张图片

广播攻击 (small e)

B选择的e较小,且几次加密的信息m相同

c1 = m ^ e mod n1
c2 = m ^ e mod n2
c3 = m ^ e mod n3

根据[中国剩余定理]计算出cx (https://baike.baidu.com/item/%E5%AD%99%E5%AD%90%E5%AE%9A%E7%90%86/2841597?fromtitle=%E4%B8%AD%E5%9B%BD%E5%89%A9%E4%BD%99%E5%AE%9A%E7%90%86&fromid=11200132&fr=aladdin)

cx = m ^ 3 mod n1n2n3

对cx开三次方即可得到m

例题5、

n1=3184273000603708051896374137923057198211094334842809424557962637794782294801864792420893981755335234175142208934607215450839499631632458122838975649379772518852683463113247078803930872516973728738441477403263782150655688059864351001382601317415565787754938842833471427987313456225237136522569229199767714029113186946128721192639026803724478281061905375839801790561887634449609831256952724334929701867762108269704279672633736501207795045621445495684841694147281740978497396349681590938795053712843157558911448741672887265329408905522288945271247306062164169083799080581576844026544196507061780947576680321314108392647
e1=3
c1=1865207266799996243228817304785105186128313762026459662106438140987810119638576035455810918192610162974644804325700727033397631237565568309250447997692957047117948414605262707210503694076217753671199536395804376735980939475943306552210578935155360834667472016665676094531937175375189119576834726559914368446599747335583484488400218726081559377872231484682832323487891260169871842137971634220678913614199693895028277295936272132967943949212045133910468330075523225546555284462267175192647725355824897112645323595082325014848213949996106219123466528151645552827456831521727714312875817605387842910776003281468632177134
n2=5947242496412590165886022830117979031270849438565414718945540769656801659060145414012439040675436355554730985758732378038388730643183490705333543982433697770161034284340019436698252581207947899331724870247713348112513551744856203618474445966867979101613482134937251288025326239040546312157563226597808206728974063266847623663376197620795712476379614206184866600891814266441420096950858632266041468432728039098235219202429667813023866281876260313319408789799168671371967931911067693233943058351630136956131977019545880612393331500862363561705686291751808121307659369950091831457743559304935521177616970170121899847499
e2=3
c2=5329839376003386424531390530291755253783136537372306970258380778841411938968277820730736914044469924457037948618895817081183967847747849864612418345235974595324704489015633061981019979529325160156304788684511539016419138205029103288532049627836528718735354249479611169423184818835225060964820758060879400538668119624133333610160075028319073912202797807572706643548716922456176911646487273693616082924469901327385014547016959814916531765625265956350393314015819147117668292817998166701212842593565668481237562334160409111280245721133821729698831956884879852048076463825139448367617549344936160289592539599562603182308
n3=1619477568975952701259057615681948469998598727467548920567987371583808541608865794715674249299251982223554463245267913319011439540372690719318616625432515649945415072879857399935962243093033020212726392446482688722523597117616715421450234027457487384685541370636909037532024494764235715359165776748613722244237454618534625777019222793493467304333894049695939845924618377175428182083061659479862995561534893358459425241809160308555104350834921888371703396141707886926364364568511870728602018394122222536081801604623257186337824087463875063459411092787941122075073888812296045329605966948887174839303850054066549742331
e3=3
c3=56537261971453461628378794041129292234708934241500623599492236054809993089458119558859048280887450688383162997431051833341166123967621065567645821142714578598634926086505265631519468437627610732981529419608470499569773474149861616309893753444615252761070299110608388653964994342395869950839385196794419980540285703423073352381718752590813640713624989959818173320902028724671829912267909600281104679202709735798484743339777607531820611774508541070974653249746559131361804224877198967927897074633208445500712006065089400145934143164857831974809927265562676588011008120329753404441512900600390241426493424854902736641

三次都使用e=3作为加密指数
假设三次加密的明文是相同的

'''
Created on Dec 14, 2011

@author: pablocelayes
'''

import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
import sys
sys.setrecursionlimit(10000000)

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 = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227

    e =12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
    print hack_RSA(e, n)

输出
RSA学习2 —— 公钥密码_第9张图片

相关m1、m2攻击

A使用同一公钥对两个具有某种线性关系的消息m1,m2进行加密为c1,c2
发给B
攻击者可以获得m1,m2

假设线性关系为 m1 = a * m2 + b
且 e = 3 可以得到 m2 = 在这里插入图片描述
要怎么知道a和b
且满足以上关系?
题目会给吧?

def relate_message_attack(a, b, c1, c2, n):
b3 = gmpy2.powmod(b, 3, n)
part1 = b * (c1 + 2 * c2 - b3) % n
part2 = a * (c1 - c2 + 2 * b3) % n
part2 = gmpy2.invert(part2, n)
return part1 * part2 % n

DSA

离散对数问题
使用相同的k 和 r
。。。

你可能感兴趣的:(Crypto)