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 keygen(): # generate an RSA public / private keypair (e, d, N) = rsa_keygen(MODULUS_SIZE) # write the keypairs to file write_key_file(PUBKEY_FILE, (MODULUS_SIZE, e, N)) write_key_file(PRIVKEY_FILE, (MODULUS_SIZE, d, N))
def rsa_parity_oracle(): pub, priv = rsa.rsa_keygen() # returns True if even def parity_oracle(c): p = rsa.decrypt(priv, c) if long(binascii.hexlify(p), 16) % 2 == 0: return True return False return parity_oracle, pub, priv
def get_rsa_unpadded_dec_oracle(bitlen=1024): # keypair pub, priv = rsa.rsa_keygen(bitlen) # ciphertexts already decrypted c_dict = {} def dec_oracle(c): if c in c_dict: print "C has already been decrypted!" return m = rsa.decrypt(priv, c) c_dict[c] = time.time() return m return pub, dec_oracle