v = hex(long(i))[2:-1] if len(v) & 1: v = '0' + v return v.decode('hex') def extract_bits(priv, pub, cipher): N = pub[1] c2 = rsa.raw_encrypt(pub, 2) cipher = (cipher * c2) % N for _ in range(1024): yield oracle(priv, cipher) cipher = (cipher * c2) % N if __name__ == '__main__': pub, priv = rsa.gen_rsa(1024, rsa.PUBLIC_EXP) N = pub[1] cipher = rsa.raw_encrypt(pub, plain_i) lo, hi = 0, N for b in extract_bits(priv, pub, cipher): mid = (lo + hi) / 2 if b == 1: lo = mid else: hi = mid # whoops, the last byte is trashed (div accuracy?). nevermind. print decode_int(hi)[:-1]
def decode_int(i): v = hex(long(i))[2:-1] if len(v) & 1: v = '0' + v return v.decode('hex') def extract_bits(priv, pub, cipher): N = pub[1] c2 = rsa.raw_encrypt(pub, 2) cipher = (cipher * c2) % N for _ in range(1024): yield oracle(priv, cipher) cipher = (cipher * c2) % N if __name__ == '__main__': pub, priv = rsa.gen_rsa(1024, rsa.PUBLIC_EXP) N = pub[1] cipher = rsa.raw_encrypt(pub, plain_i) lo, hi = 0, N for b in extract_bits(priv, pub, cipher): mid = (lo + hi) / 2 if b == 1: lo = mid else: hi = mid # whoops, the last byte is trashed (div accuracy?). nevermind. print decode_int(hi)[:-1]
import rsa import sys def pkcs1_oracle(priv, cipher): plain = rsa.raw_decrypt(priv, cipher) N = priv[1] modlen = rsa.bit_len(N) topbyte = (plain >> (modlen - 8)) & 0xff topbyte2 = (plain >> (modlen - 16)) & 0xff return topbyte == 0x00 and topbyte2 == 0x02 if __name__ == '__main__': modsz = int(sys.argv[1]) pub, priv = rsa.gen_rsa(modsz, 3) e, n = pub n_bytes = modsz / 8 B = 2**(8 * (n_bytes - 2)) pt = 'kick it, CC'.encode('hex') pad = 'af' * (n_bytes - 3 - len(pt) / 2) msg = '0002' + pad + '00' + pt msg = long(msg, 16) ct = rsa.raw_encrypt(pub, msg) assert pkcs1_oracle(priv, ct) # don't need to do blinding here i = 1 M0 = [(2 * B, 3 * B - 1)] s0 = 1
import rsa import sys def pkcs1_oracle(priv, cipher): plain = rsa.raw_decrypt(priv, cipher) # print plain N = priv[1] modlen = rsa.bit_len(N) topbyte = (plain >> (modlen - 8)) & 0xff topbyte2 = (plain >> (modlen - 16)) & 0xff return topbyte == 0x00 and topbyte2 == 0x02 if __name__ == '__main__': modsz = int(sys.argv[1]) pub, priv = rsa.gen_rsa(modsz, 3) e, n = pub n_bytes = modsz / 8 B = 2 ** (8 * (n_bytes - 2)) pt = 'kick it, CC'.encode('hex') pad = 'af' * (n_bytes - 3 - len(pt) / 2) msg = '0002' + pad + '00' + pt msg = long(msg, 16) ct = rsa.raw_encrypt(pub, msg) assert pkcs1_oracle(priv, ct) # don't need to do blinding here i = 1 M0 = [(2 * B, 3 * B - 1)] s0 = 1 c0 = (ct * rsa.raw_encrypt(pub, s0)) % n
return rsa.raw_decrypt(priv, mr) def bad_pkcs1_verify(pub, sig, msg): e, n = pub modlen = rsa.byte_len(n) mr = rsa.raw_encrypt(pub, sig) h = sha1(msg).hexdigest().lower() mrh = ('%0' + str(modlen * 2) + 'x') % mr if match('^0001ff+00' + asn1_sha1_prefix + h, mrh): return 'ok' else: return 'bad signature' if __name__ == '__main__': pub, priv = rsa.gen_rsa(1024, 3) msg = 'hi mom' # check good_sig = pkcs1_sign(priv, msg) assert 'ok' == bad_pkcs1_verify(pub, good_sig, msg) # forge mr = '0001ff00' + asn1_sha1_prefix + sha1(msg).hexdigest() # right-pad to approx half the interval mr += '7f' * (128 - 4 - len(asn1_sha1_prefix) / 2 - 20) mr = long(mr, 16) near_root = rsa.cuberoot_approx(mr) mr = near_root ** 3 bad_sig = rsa.cuberoot(mr)
import rsa if __name__ == '__main__': pubkeys = [] for _ in range(3): pub, priv = rsa.gen_rsa(1024, 3) pubkeys.append(pub) m = 0x1235123 ciphertexts = [] for pub in pubkeys: e = rsa.raw_encrypt(pub, m) ciphertexts.append(e) # pubkeys are e, n tuples moduli = [pubkeys[x][1] for x in range(3)] m_s = [ moduli[1] * moduli[2], moduli[0] * moduli[2], moduli[0] * moduli[1] ] n_012 = moduli[0] * moduli[1] * moduli[2] magic = 0 for i in range(3): inv = rsa.invmod(m_s[i], moduli[i]) magic += ciphertexts[i] * m_s[i] * inv magic %= n_012 assert m == rsa.cuberoot(magic) print 'ok'