def plot_crypt(max_key_length, trials): key_lengths = range(8, max_key_length + 1) encryption_times = [] for key_length in key_lengths: print('Computing key length', key_length) key_length_time = 0 for _ in range(trials): e, _, n = generate_keys(key_length) time_before = time() crypt(n - 1, (e, n)) time_after = time() key_length_time += time_after - time_before encryption_times.append(key_length_time / trials) pyplot.plot(key_lengths, encryption_times) pyplot.title('Encryption Time vs. Key Length') pyplot.xlabel('Key Length (in bits)') pyplot.ylabel('Encryption Time (in seconds)') pyplot.show()
import rsa # FAKE WORKING EXEMPLE on PYTHON 3 # from https://github.com/Theo6898/Python-RSA-module # version 1.0 - 15 november 2015 # For security issues, server and user need to know their respective public keys for sure # You need a trust authoritie to check if the public keys are correct #Generating key pairs publicKeyUser, privateKeyUser = rsa.generateKeyPair("RSA-1024") publicKeyServer, privateKeyServer = rsa.generateKeyPair("RSA-1024") # user crypt message with server's public key and sign it with its own private key data = ["Hello this a message", "And another one !"] data_crypted = rsa.crypt(data, publicKeyServer) data_signed = rsa.sign(data, privateKeyUser) # server decrypt the message with its own private key and check if the message has been signed by the user itself data_decrypted = rsa.decrypt(data_crypted, privateKeyServer) if rsa.check_signature(data_decrypted, data_signed, publicKeyUser) == True: print("Message received :\n", data_decrypted) else: print("Invalid signature, man in the middle attack")
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.
bounds = [0, n] start = time.time() for i in range(2048): p = parity(multiply(ciphertext, 2**(i + 1), e, n)) half_the_dist = (bounds[1] - bounds[0]) / 2 if p == 0: bounds = [bounds[0], bounds[1] - half_the_dist] elif p == 1: bounds = [bounds[0] + half_the_dist, bounds[1]] if i % 16 == 0: print p, i, cleanup(rsa.i2s(bounds[1]), '_') # get 256 char wide screen end = time.time() dur = round(end - start, 1) print "--------" for b in bounds: print rsa.i2s(b) print "2048 oracularities in", dur, "s =", round(2048 / dur, 1), "per s." #### tests #### hi = 'Hi' c_hi = rsa.encrypt_string(hi, pubkey) D = multiply(c_hi, 2, pubkey[0], pubkey[1]) assert rsa.s2i(hi) * 2 == rsa.crypt(D, privkey) warn("Passed assertions:", __file__)
# theory, I think we could just cube-root it, but oh well. bounds = [0, n] start = time.time() for i in range(2048): p = parity(multiply(ciphertext, 2**(i+1), e, n)) half_the_dist = (bounds[1] - bounds[0]) / 2 if p == 0: bounds = [bounds[0], bounds[1] - half_the_dist] elif p == 1: bounds = [bounds[0] + half_the_dist, bounds[1]] if i % 16 == 0: print p, i, cleanup(rsa.i2s(bounds[1]), '_') # get 256 char wide screen end = time.time() dur = round(end - start, 1) print "--------" for b in bounds: print rsa.i2s(b) print "2048 oracularities in", dur, "s =", round(2048 / dur, 1), "per s." #### tests #### hi = 'Hi' c_hi = rsa.encrypt_string(hi, pubkey) D = multiply(c_hi, 2, pubkey[0], pubkey[1]) assert rsa.s2i(hi) * 2 == rsa.crypt(D, privkey) warn("Passed assertions:", __file__)
# RSA numbers below RSA-1024 are not secured enough, # use them for better performances during developement # - "RSA-2048" # - "RSA-1536" # - "RSA-1024" # - "RSA-896" # - "RSA-768" # - "RSA-704" # - "RSA-576" #--------------------------------------------------------------------------------- # Crypt a message #--------------------------------------------------------------------------------- data = ["abc", 1, 7] data_crypted = rsa.crypt(data, key) # it takes 2 arguments : # - a LIST of datas to encrypt (it can only contain int and str) # - a key (public or private), the message can be decrypted with the opposite key # exemple : by encrypting a message with a public key you will be able to decrypt # it with the corresponding private key and vice-versa. # the function return a list of the encrypted datas # in this case it could return something like that # [[89, 23, 41], 31, 97] # as you can see every single letter in the 'data' string 'abc' is transformed by a number #--------------------------------------------------------------------------------- # Decrypt a message
parser = argparse.ArgumentParser() parsers = parser.add_subparsers(dest='command') generate_keys_parser = parsers.add_parser('generate_keys') generate_keys_parser.add_argument('seed_length', type=int) crypt_parser = parsers.add_parser('crypt', aliases=['encrypt', 'decrypt']) crypt_parser.add_argument('key', type=int, nargs=2) crypt_parser.add_argument('message', type=int) crack_parser = parsers.add_parser('crack') crack_parser.add_argument('key', type=int, nargs=2) plot_parser = parsers.add_parser('plot') plot_parser.add_argument('operation', type=str, choices=['crypt', 'crack']) plot_parser.add_argument('max_key_length', type=int) plot_parser.add_argument('trials', type=int) args = parser.parse_args() if args.command == 'generate_keys': print(generate_keys(args.seed_length)) elif args.command == 'encrypt' or args.command == 'decrypt': print(crypt(args.message, args.key)) elif args.command == 'crack': print(math_attack(*args.key)) elif args.command == 'plot': if args.operation == 'crypt': plot_crypt(args.max_key_length, args.trials) if args.operation == 'crack': plot_crack(args.max_key_length, args.trials) else: raise argparse.ArgumentTypeError('Invalid command')