p = getPrime(256) a = getPrime(256) b = getPrime(256) E = EllipticCurve(GF(p),[a,b]) m = E.random_point() G = E.random_point() k = getPrime(18) K = k * G r = getPrime(256) c1 = m + r * K
p = koZP3YQAklARRNrmYfjxoKIAXegOcG4jMOmKb08uESOkCCn72d6UM2NWgefYPEMq4EJ1M0jKaqt02Guo5Ubccjqg4QZaaHbScREx38UMLQKwG0LcDd8VFX1zkobc1ZQn4L3DhKQrgJZI55todgOdJuHN532bxScAvOF26gJyQclPtRHn3M6SHrRCEXzzmszd68PJlLB6HaabrRrCW9ZoAYSZetM5jDBtNCJLpR0CBZUUk3Oeh2MZQu2vk8DZ1QqNG49hlxGfawp1FXvAZPdMwixzkhEQnbCDcOKzYyT6BZF2Dfd940tazl7HNOswuIpLsqXQ2h56guGngMeYfMXEZV09fsB3TE0N934CLF8TbZnzFzEkOe8TPTK2mWPVSrgmbsGHnxgYWhaRQWg3yosgDfrEa5qfVl9De41PVtTw024gltovypMXK5XMhuhogs0EMN7hkLapLn6lMj p的格式为p={p}
a = 87425770561190618633288232353256495656281438408946725202136726983601884085917 b = 107879772066707091306779801409109036008421651378615140327877558014536331974777 K = (49293150360761418309411209621405185437426003792008480206387047056777011104939 : 43598371886286324285673726736628847559547403221353820773139325027318579443479) G = (34031022567935512558184471533035716554557378321289293120392294258731566673565 : 74331715224220154299708533566163247663094029276428146274456519014761122295496) 私钥k小于1000000 c1 = (3315847183153421424358678117707706758962521458183324187760613108746362414091 : 61422809633368910312843316855658127170184420570309973276760547643460231548014) c2 = (12838481482175070256758359669437500951915904121998959094172291545942862161864 : 60841550842604234546787351747017749679783606696419878692095419214989669624971) cipher_left = 75142205156781095042041227504637709079517729950375899059488581605798510465939 cipher_right = 61560856815190247060747741878070276409743228362585436028144398174723191051815
当时看到这道题的时候,这不就是个ecc的板子题嘛!只要再多搞个k爆破就可以出来了
但是我还是有点低估了这道题
p = koZP3YQAklARRNrmYfjxoKIAXegOcG4jMOmKb08uESOkCCn72d6UM2NWgefYPEMq4EJ1M0jKaqt02Guo5Ubccjqg4QZaaHbScREx38UMLQKwG0LcDd8VFX1zkobc1ZQn4L3DhKQrgJZI55todgOdJuHN532bxScAvOF26gJyQclPtRHn3M6SHrRCEXzzmszd68PJlLB6HaabrRrCW9ZoAYSZetM5jDBtNCJLpR0CBZUUk3Oeh2MZQu2vk8DZ1QqNG49hlxGfawp1FXvAZPdMwixzkhEQnbCDcOKzYyT6BZF2Dfd940tazl7HNOswuIpLsqXQ2h56guGngMeYfMXEZV09fsB3TE0N934CLF8TbZnzFzEkOe8TPTK2mWPVSrgmbsGHnxgYWhaRQWg3yosgDfrEa5qfVl9De41PVtTw024gltovypMXK5XMhuhogs0EMN7hkLapLn6lMj
额,这p是什么东西?
尝试了很多种编码方式,就是解不出p,“p的格式为p={p}”也没看明白是什么意思
后面朋友把学长的脚本分享给了我,我发现我遗漏了一个很重要的点,就是椭圆曲线的方程: $$ y^2=x^3+ax+b mod p $$ 因为K和G都在曲线上,所以我们可以把K和G两个点代入到椭圆方程当中求kp $$ k1p=x_K^3+ax+b-y_K^2 $$ $$ k2p=x_G^3+ax+b-y_G^2 $$ 然后在gcd(k1p,k2p),最后就可以把p给求出来
import os import hashlib from Crypto.Util.number import * from Crypto.PublicKey import DSA import random defgen_proof_key(): password = 'happy_the_year_of_loong' getin = '' for i in password: if random.randint(0, 1): getin += i.lower() else: getin += i.upper() ans = hashlib.sha256(getin.encode()).hexdigest() return getin,ans
defsign(m,pri): k = int(hashlib.md5(os.urandom(20)).hexdigest(),16) H = int(hashlib.sha256(m).hexdigest(),16) r = pow(g,k,p) % q s = pow(k,-1,q) * (H + pri * r) % q return r,s
defverify(pub,m,signature): r,s = signature if r <= 0or r >= q or s <= 0or s >= q: returnFalse w = pow(s,-1,q) H = int(hashlib.sha256(m).hexdigest(),16) u1 = H * w % q u2 = r * w % q v = (pow(g,u1,p) * pow(pub,u2,p) % p) % q return v == r deflogin(): print('Hello sir,Plz login first') menu = ''' 1.sign 2.verify 3.get my key ''' times = 8 whileTrue: print(menu) if times < 0: print('Timeout!') returnFalse choice = int(input('>')) if choice == 1: name = input('Username:').encode() ifb'admin'in name: print('Get out!') returnFalse r,s = sign(name,pri) print(f'This is your signature -- > {r},{s}') times -= 1 elif choice == 2: print('Sure,Plz input your signature') print(pri) r = int(input('r:')) s = int(input('s:')) if verify(pub,b'admin',(r,s)) == True: print('login success!') returnTrue else: print('you are not admin') returnFalse elif choice == 3: print(f'Oh,your key is {(p,q,g)}') getin,ans = gen_proof_key() print(f'Your gift --> {ans[:6]}') your_token = input('Plz input your token\n>') if your_token != getin: print('Get out!') exit(0)
key = DSA.generate(1024) p, q, g = key.p, key.q, key.g pri, pub = gen_key() if login() == False: exit(0) print(open('/flag','r').read())
defsign(m,pri): k = int(hashlib.md5(os.urandom(20)).hexdigest(),16) H = int(hashlib.sha256(m).hexdigest(),16) r = pow(g,k,p) % q s = pow(k,-1,q) * (H + pri * r) % q return r,s
defverify(pub,m,signature): r,s = signature if r <= 0or r >= q or s <= 0or s >= q: returnFalse w = pow(s,-1,q) H = int(hashlib.sha256(m).hexdigest(),16) u1 = H * w % q u2 = r * w % q v = (pow(g,u1,p) * pow(pub,u2,p) % p) % q return v == r
我们能够看得出,这里考察的是隐藏数问题(HNP / Hidden Number Problem),用admin来检验签名