# chal42.py - e=3 RSA # # Copyright (C) 2015 Andrew J. Zimolzak <*****@*****.**>, # and licensed under GNU GPL version 3. Full notice is found in # the file 'LICENSE' in the same directory as this file. from cryptopals import warn, cuberoot import rsa import random import cryptopals from hashlib import sha1 message = 'Blah blah' bits = 1024 U, R = rsa.keypair(bits) hash = sha1(message).digest() def pkcs_1_5(string, bits): """Pad a string to specified number of bits. Specifically, start with 0x0001, then a bunch of 0xFF, then 0x00, then some imitation ASN.1 data, then the string. In real life, ASN.1 data encodes the length of the string, which I do too, to a point. There's also some other data in there, and I completely ignore the implementation of 'other ASN.1 data'. """ assert len(string) < 256 assert bits % 8 == 0 byte_goal = bits / 8 prepend = "\x00\x01" append = "\x00ASN.1" + chr(len(string))
#!/usr/bin/env python # chal46.py - RSA parity oracle # # Copyright (C) 2015 Andrew J. Zimolzak <*****@*****.**>, # and licensed under GNU GPL version 3. Full notice is found in # the file 'LICENSE' in the same directory as this file. from cryptopals import warn import rsa import base64 import time print "Generating keypair..." pubkey, privkey = rsa.keypair(1024) print "Done!" e = pubkey[0] n = pubkey[1] def parity(ciphertext): """Ciphertext is an integer. Depends on privkey.""" decrypt_int = rsa.crypt(ciphertext, privkey) return int(decrypt_int % 2) # int, not a long. def multiply(ciphertext, k, e, n): return (ciphertext * k ** e) % n def cleanup(string, substitution=''): safe = '' for c in string: if 32 <= ord(c) <= 126:
#!/usr/bin/env python # chal46.py - RSA parity oracle # # Copyright (C) 2015 Andrew J. Zimolzak <*****@*****.**>, # and licensed under GNU GPL version 3. Full notice is found in # the file 'LICENSE' in the same directory as this file. from cryptopals import warn import rsa import base64 import time print "Generating keypair..." pubkey, privkey = rsa.keypair(1024) print "Done!" e = pubkey[0] n = pubkey[1] def parity(ciphertext): """Ciphertext is an integer. Depends on privkey.""" decrypt_int = rsa.crypt(ciphertext, privkey) return int(decrypt_int % 2) # int, not a long. def multiply(ciphertext, k, e, n): return (ciphertext * k**e) % n def cleanup(string, substitution=''):
# and licensed under GNU GPL version 3. Full notice is found in # the file 'LICENSE' in the same directory as this file. from cryptopals import warn, cuberoot import rsa import copy 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):
def __init__(self, bits): self.log = [] self.pub, self.priv = rsa.keypair(bits)
return prepend + ("\xff" * bytes_to_add) + append + string 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" Bits = 768 / 2 pubkey, privkey = rsa.keypair(Bits) print pubkey[1].bit_length(), "bit modulus" short_message = """Now these points of data make a beautiful line And we're out of beta; we're releasing on time""" m = pkcs_1(short_message, Bits * 2) # Bits*2 = length of n c = rsa.encrypt_string(m, pubkey) print "Oracle says that raw ciphertext conforms?", oracle(c, privkey, Bits * 2) assert oracle(c, privkey, Bits*2) #### Step 1 (Easy if c is already PKCS conforming) e = pubkey[0] n = pubkey[1] k = Bits * 2 / 8 # Length of n in bytes B = 2 ** (8 * (k - 2)) s = [1]
import hypothesis.strategies as st from hypothesis import given import rsa public, private = rsa.keypair() # to use for encode/decode test @given(st.text(max_size=8)) def test_encode_decode(s): assert rsa.decode(rsa.encode(s, public), private) == s