def bleichenbacher_rsa_forge_sig(m): """ Requires e = 3 """ # keypair pub, priv = rsa.rsa_keygen(1024, 3) print "M is '%s'" % m h = hashlib.sha1(m).digest() block = '\x00\x01\xff\x00' + rsa.ASN1_sha1_prefix + h # now add some garbage at the end to play with block += (128-len(block))*'\x00' # figure out the approximate cube root (since e = 3) block_as_num = long(binascii.hexlify(block), 16) print "Forged block to start with: ", repr(block) #print "as integer: ", block_as_num # closest cube root forged_sig = approx_cube_root(block_as_num)+1 next_cube = forged_sig ** 3 print "Forged block: ", repr(rsa._tohex(next_cube)) print "Forged signature: ", repr(forged_sig) # check the forged signature print "\nChecking forged signature: ", rsa.vuln_pkcs1_verify(pub, m, rsa._tohex(forged_sig))
def rsa_decrypt_with_parity(p): oracle, pub, priv = rsa_parity_oracle() n = pub[1] c = rsa.encrypt(pub, p) bs = bits(pub, priv, c, oracle) # binary search low, high = 0, n for b in bs: mid = low + (high-low)/2 if b: high = mid else: low = mid print rsa._tohex(high)
def unpadded_msg_recovery_oracle(): pub, oracle = get_rsa_unpadded_dec_oracle(1024) m = "Hello World!" print "M is '%s'" % m c = rsa.encrypt(pub, m) print "C is %d\n" % c # use the decryption oracle print "Using decryption oracle..." m2 = oracle(c) print "Decrypted '%s'\n" % m2 print "Testing that decryption oracle will reject this ciphertext" print "Using decryption oracle..." m2 = oracle(c) # pick random S > 1 mod N such that S has a multiplicative inverse mod N print "\nSearching for suitable S > 1 mod N" E, N = pub S, S_inv = None, None while True: S = random.randint(2, N-1) if S == E: continue S_inv = rsa.invmod(S, N) if S_inv: break print "Doing the attack with S == %d, S_inv == %d" % (S, S_inv) c_prime = (rsa.modexp(S, E, N) * c) % N print "Using decryption oracle..." m_prime = long(binascii.hexlify(oracle(c_prime)), 16) m2 = rsa._tohex(m_prime * S_inv % N) print "Messsage is '%s'" % m2