def decrypt(self, rsa_blob): """Expects numeric argument, not string.""" this_hash = sha1(str(rsa_blob)).digest() for logged_hash in self.log: if this_hash == logged_hash: return "GO AWAY." self.log.append(this_hash) return rsa.decrypt_string(rsa_blob, self.priv)
def run_tests(m): """ Small sanity test suite """ menc = PKCS1_encode(m, k) print("1. (un)pad:", PKCS1_decode(menc) == m) m1 = rsa.decrypt_string(sk, rsa.encrypt_string(pk, m)) print("2. rsa w/o pad:", m == m1) m2 = PKCS1_decode(rsa.decrypt_string(sk, rsa.encrypt_string(pk, menc))) print("3. rsa w/ pad:", m == m2) m3 = oracle(rsa.encrypt_string(pk, menc)) == True print("4. oracle well-formed:", m3) m4 = oracle(rsa.encrypt_string(pk, m)) == False print("5. oracle not well-formed", m4)
def oracle(ciphertext, privkey, bits): """bits should equal the max bits of a message, not bit length of key. """ plaintext = rsa.decrypt_string(ciphertext, privkey) assert bits % 8 == 0 bytes = bits / 8 diff = bytes - len(plaintext) plaintext = "\x00" * diff + plaintext assert len(plaintext) == bytes, len(plaintext) return plaintext[0] == "\x00" and plaintext[1] == "\x02"
def oracle(ciphertext): """ Placeholder for some server which talks RSA PKCS1 v1.5 It can be used as an oracle, because it tells whether the given ciphertext decodes to a valid PKCS1 v1.5 encoding scheme, i.e. first 2 bytes of the plaintext == "\x00\x02" """ global queries queries += 1 t = time.perf_counter() if queries % 500 == 0: print("Query #{} ({} s)".format(queries, round(t - t_start, 3))) encoded = rsa.decrypt_string(sk, ciphertext) if len(encoded) > k: raise Exception("Invalid PKCS1 encoding after decryption!") if len(encoded) < k: zero_pad = b"\x00" * (k - len(encoded)) encoded = zero_pad + encoded return encoded[0:2] == b"\x00\x02"
def verify(sig, message, pubkey): block = rsa.decrypt_string(sig, pubkey) for i in range((bits/8) - len(block)): block = "\x00" + block return sha1(message).digest() == unpad(block)
k = 3 # How many times to encrypt the same plaintext, under different # public keys. message = 'Hello, world! I am gonna encrypt this thrice; uh oh.' bits = len(message) * 8 / 2 c = [None] * k n = [None] * k for i in range(k): U, R = rsa.keypair(bits) ciphertext = rsa.encrypt_string(message, U) c[i] = ciphertext n[i] = U[1] # the second part of the pubkey print "public " + str(U[1])[:60] + "...." print "ciphertext " + str(ciphertext)[:60] + "...." decrypt = rsa.decrypt_string(ciphertext, R) print print "Bob gets this message:", decrypt #### Eve # Calculate products of the moduli (pubkeys) EXCEPT pubkey number i. ms = [None] * k for i in range(k): x = copy.copy(n) del x[i] ms[i] = reduce(lambda a, b: a * b, x) # Work thru Chinese Remainder Theorem result = 0 for i in range(k):
k = 3 # How many times to encrypt the same plaintext, under different # public keys. message = 'Hello, world! I am gonna encrypt this thrice; uh oh.' bits = len(message) * 8 / 2 c = [None]*k n = [None]*k for i in range(k): U, R = rsa.keypair(bits) ciphertext = rsa.encrypt_string(message, U) c[i] = ciphertext n[i] = U[1] # the second part of the pubkey print "public " + str(U[1])[:60] + "...." print "ciphertext " + str(ciphertext)[:60] + "...." decrypt = rsa.decrypt_string(ciphertext, R) print print "Bob gets this message:", decrypt #### Eve # Calculate products of the moduli (pubkeys) EXCEPT pubkey number i. ms = [None]*k for i in range(k): x = copy.copy(n) del x[i] ms[i] = reduce(lambda a, b: a*b, x) # Work thru Chinese Remainder Theorem result = 0 for i in range(k):