def test_parity_oracle(): pub, priv = generate_seq_rsa_keypairs(bitlength=1024, e=65535) set_oracle_key(priv) test_text = "TESTME123" test_i = int(binascii.hexlify(test_text), 16) logging.debug("test: {s} ({i})".format(s=test_text, i=test_i)) cipher = simple_rsa(test_i, pub) logging.debug("cipher: {c}".format(c=cipher)) v = parity_oracle(cipher) logging.debug("oracle: {v}".format(v=v)) assert (v == False)
def rsa_pkcs15_sign(data, priv_key, ksize=1024): ksize = ksize // 8 # bits2bytes padded_sig = "\x00\x01" padded_sig += ('\xff' * (ksize - 3 - len(data))) + '\x00' padded_sig += data assert (len(padded_sig) == ksize) # this gets rid of leading zeros... padded_sig_i = str2int16(padded_sig) sig = simple_rsa(padded_sig_i, priv_key) return sig
def parity_oracle_decrypt(ciphertext, pub, oracle, hollywood=True): e, n = pub up = n low = 0 c = 1 for _ in xrange(bitlength(ciphertext) + 1): c *= 2 mm = simple_rsa(c, pub) if oracle(ciphertext * mm): up = (up + low) / 2 else: low = (up + low) / 2 if hollywood: print repr(int2str(up)) return up
def simple_rsa_pkcs15_verify_insecure(msg, esig, key): dsig = int2str(simple_rsa(esig, key)) logging.debug('verify decrypt: {d}'.format(d=binascii.hexlify(dsig))) # python int drops unecessary leading zeros... assert (dsig.startswith('\x00\x01\xff') or dsig.startswith('\x01\xff')) asn1_start = dsig.find("\xff\x00") assert (asn1_start != -1) asn1_data = dsig[asn1_start + 2:] oid, vhash, offset = simple_decode_asn1_goop(asn1_data) new = "" if oid[-4] != OID_RSA_INT: raise ValueError("unknown oid: {o}".format(o=oid)) if oid[-1] == OID_RSA_MD5_INT: new = hashlib.md5(msg).digest() else: raise ValueError("unsupported rsa alg: {o}".format(o=oid[-1])) return new == vhash
def parity_oracle(ciphertext): global challenge46_priv plaintext = simple_rsa(ciphertext, challenge46_priv) return plaintext & 1 == 0