def test_sign_RSA(self): message = b'hi mom' m = sha1() m.update(message) message_hash = m.digest() public, private = ck.gen_RSA_keys() signature, plain = sign_RSA(message_hash, private) self.assertTrue(verify_RSA(message_hash, signature, public))
def get_parity_oracle(): """Return RSA public key, and oracle function, which will decrypt messages encrypted with the public key and return True or False depending on whether the plaintext (as integer) is even or odd """ public, private = ck.gen_RSA_keys() previous = [] def oracle(cipher): plain = ck.cipher_RSA(cipher, private) return not (plain % 2) return public, oracle
def test_40(self): plain = randbelow(2**128) public_keys = [] ciphertexts = [] for _ in range(3): public, _ = ck.gen_RSA_keys() cipher = ck.cipher_RSA(plain, public) public_keys.append(public) ciphertexts.append(cipher) decipher = ck.RSA_broadcast_attack(public_keys, ciphertexts) self.assertEqual(plain, decipher)
def get_message_recovery_oracle(): """Return RSA public key, and an oracle function, which will decrypt and return any message encrypted with the public key exactly once """ public, private = ck.gen_RSA_keys() previous = [] def oracle(cipher): if cipher in previous: raise ValueError('Ciphertext previously submitted') previous.append(cipher) return ck.cipher_RSA(cipher, private) return public, oracle
def get_PKCS_oracle(N): """Return RSA public key, and oracle function, which will decrypt messages encrypted with the public key and return True or False depending on whether or not the plaintest has a valid PCKS#1v1.5 padding""" strong = N > 512 public, private = ck.gen_RSA_keys(N=N, strong=strong) B = 2**(N - 16) def oracle(cipher): plain = ck.cipher_RSA(cipher, private) return (plain >= 2 * B) and (plain < 3 * B) return public, oracle
def test_42(self): # we only know the public key, so we have to forge the signature public, _ = ck.gen_RSA_keys(N=3072) message = b'hi mom' m = sha1() m.update(message) message_hash = m.digest() block = bytes([0]) + SHA1_ASN + message_hash """Bleichenbacher's 'pencil and paper' attack strategy doesn't work for smaller moduli (e.g., N=1024), and via brute-forcing I couldn't find a zero-padded forged signature that worked, so I'm saying screw it and doing this for 3072 bit RSA""" D = int.from_bytes(block, 'big') M = 2**288 - D F = 2**1019 - 2**34 * M // 3 forged = cu.int_to_bytes(F) self.assertTrue(verify_RSA(message_hash, forged, public))
def test_39(self): public, private = ck.gen_RSA_keys() plain = 42 cipher = ck.cipher_RSA(plain, public) decipher = ck.cipher_RSA(cipher, private) self.assertEqual(plain, decipher)