class oracle: def __init__(self): self.rsa = RSA() self.pub,self.priv = self.rsa.keygen(l=512) # 1024 bits key def getpubkey(self): return self.pub def iseven(self,ct): return ord(self.rsa.decrypt(ct,self.priv)[-1]) & 1 == 0
def oracle(key, c): """ oracle function for c47 """ rsa = RSA() try: m = rsa.decrypt(c, key) except: return False if m[0:2] == '\x00\x02': return True return False
#!/usr/bin/env python from c39 import RSA # RSA from c36 import i2s, s2i if __name__ == "__main__": msg = "attack after the breakfast" rsa = RSA() pub,priv = rsa.keygen() C = rsa.encrypt(msg,pub) assert rsa.decrypt(C,priv) == msg, "bug in my RSA, decryption didn't provide the same clear text" S = 3 # lowest possible S C1 = list() # the cipher text is a list for ct in C: # lets iterate over the ciphertext C1.append(i2s((pow(S,pub[0],pub[1])*s2i(ct)) % pub[1])) # if C1 != C: # the C1 has to be different the C P1 = rsa.decrypt(C1,priv) print i2s((s2i(P1)/S)%pub[1]) else: print "something wrong C1 and C should be different"
def verify(self,msg,sign,key): pkcs15 = PKCS15() rsa = RSA() dgst = hashlib.sha1(message).digest() return pkcs15.unpad("\x00"+rsa.decrypt(sign,key)) == dgst
def make(self,msg,key): pkcs15 = PKCS15() rsa = RSA() dgst = hashlib.sha1(message).digest() paddgst = pkcs15.pad(dgst,len(i2s(key[1]))) return rsa.encrypt(paddgst,key)
raise Exception("e not equal 3") pkcs15 = PKCS15() dgst = hashlib.sha1(mesg).digest() keylen = len(i2s(n)) getcontext().prec = keylen * 8 # this is the valid beginning forge = "\x00\x01%s\x00%s" % ("\xff" * 8, dgst) # this will be garbge garbage = "\x00" * (keylen - 8 - len(dgst) - 13) whole = s2i(forge+garbage) cr = int(pow(whole,Decimal(1)/Decimal(3)))+1 return i2s(cr) if __name__ == "__main__": message = "hi mom" re = RSA() pub1,priv1 = re.keygen(l=512,s=False) rs = RSAsign() sign = rs.make(message,priv1) assert rs.verify(message,sign,pub1), "signature algo wrong" signf = [ forging(message,pub1) ] if rs.verify(message,signf,pub1): print "ok"
def __init__(self): self.rsa = RSA() self.pub,self.priv = self.rsa.keygen(l=512) # 1024 bits key
e = key[0] # e - from the pub key n = key[1] # n - from the pub key ct = s2i(enc[0]) # encrypted message c2 = pow(2,e,n) # (2**e)%n) ct = (ct * c2) % n # we need to do this before we start counting limit = int(math.log(n,2))+1 # number of bits in the key getcontext().prec = limit # how precise our floats should be a = Decimal(0) b = Decimal(n) for x in range(limit): t = (a+b)/2 if iseven([i2s(ct)]): b = t else: a = t ct = (ct * c2) % n return i2s(int(b)).encode('string_escape') if __name__ == "__main__": txt = "VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==" c46 = oracle() pub = c46.getpubkey() rsa = RSA() enc = rsa.encrypt(base64.b64decode(txt),pub) print attack(enc,pub,c46.iseven)
count = 0 while True: c1 = (c0 * modexp(s1, e, n)) % n if oracle(prvkey, list(i2s(c1))): break s1 += 1 if count % 10 == 0: sys.stdout.write("%s \r" % (count)) sys.stdout.flush() count += 1 return s1 if __name__ == "__main__": rsa = RSA() pkcs = PKCS15t2() # clear text message text = "kick it, CC" # 256 bit key generation (pubkey, prvkey) = rsa.keygen(256) # padding PKCS#1 1.5 m = pkcs.pad(text, len(i2s(pubkey[1]))) # encrypting c = rsa.encrypt(m, pubkey) m1 = rsa.decrypt(c, prvkey)