def test_generate_dh(self, backend): generator = 2 key_size = 512 parameters = dh.generate_parameters(generator, key_size, backend) assert isinstance(parameters, dh.DHParameters) key = parameters.generate_private_key() assert isinstance(key, dh.DHPrivateKey) assert key.key_size == key_size public = key.public_key() assert isinstance(public, dh.DHPublicKey) assert public.key_size == key_size assert isinstance(parameters, dh.DHParametersWithSerialization) parameter_numbers = parameters.parameter_numbers() assert isinstance(parameter_numbers, dh.DHParameterNumbers) assert bit_length(parameter_numbers.p) == key_size assert isinstance(public, dh.DHPublicKeyWithSerialization) assert isinstance(public.public_numbers(), dh.DHPublicNumbers) assert isinstance(public.parameters(), dh.DHParameters) assert isinstance(key, dh.DHPrivateKeyWithSerialization) assert isinstance(key.private_numbers(), dh.DHPrivateNumbers) assert isinstance(key.parameters(), dh.DHParameters)
def test_public_bytes_pkcs1_unsupported(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key().public_key() with pytest.raises(ValueError): key.public_bytes( serialization.Encoding.PEM, serialization.PublicFormat.PKCS1 )
def dh_key_gen(self,request): """ Generates the parameters necessary to start the Diffie-Hellman Algorithm along with the server private and public key. After that sends to client parameters and pub_key """ logger.debug('Generating parameters and keys...') session = self.check_session_id(request.getAllHeaders()) if session == None: return json.dumps({ 'method':'NACK','content': 'Session ID not found or not passed'}, indent=4).encode('latin') if session.state != 'NEGOTIATE_ALGS': return json.dumps({ 'method':'NACK','content': 'Could not Generate keys and parameters. Invalid current state'}, indent=4).encode('latin') session.dh_parameters = dh.generate_parameters(generator=2, key_size=1024) session.private_key = session.dh_parameters.generate_private_key() session.public_key = session.private_key.public_key() parameter_num = session.dh_parameters.parameter_numbers() logger.debug('Generated keys and parameters with sucess') pub_key=session.public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo) skey = self.sign_message(pub_key) data = {'method':'ACK', 'p':parameter_num.p, 'g':parameter_num.g, 'pub_key':pub_key.decode(), 'signature':skey.decode('latin') } session.state='DH_START' message = json.dumps(data).encode('latin') return message
def DHexchange(): global s parameters = dh.generate_parameters(generator=2, key_size=512, backend=default_backend()) client_private_key = parameters.generate_private_key() client_public_key = client_private_key.public_key() serial_parameters = parameters.parameter_bytes(Encoding.PEM, ParameterFormat.PKCS3) serial_client_public_key = client_public_key.public_bytes( Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) s.send(serial_parameters) serial_serv_public_key = s.recv(1024) s.send(serial_client_public_key) serv_public_key = load_pem_public_key(serial_serv_public_key, backend=default_backend()) shared_key = client_private_key.exchange(serv_public_key) key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive(shared_key) return shared_key, key
def parameters_generator(self): # -> None logger.info('Agreement: CHECK') parameters = dh.generate_parameters(generator=2, key_size=512, backend=default_backend()) # Calcular a privada self.cli_priv_key = parameters.generate_private_key() # Calcular a pública self.cli_pub_key = self.cli_priv_key.public_key() cli_pub_key_bytes = self.cli_pub_key.public_bytes( serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo) # Primos p = parameters.parameter_numbers().p g = parameters.parameter_numbers().g message = { 'type': 'PARAMETERS_GENERATOR', 'cli_pub_key': base64.b64encode(cli_pub_key_bytes).decode('utf-8'), 'p': p, 'g': g, } self._send(message)
def gen_parameters(generator=2, key_size=2048, backend=backend): """ Generates some parameters for the DH key exchange process Note that in a DH handshake both peers must agree on a common set of parameters """ return dh.generate_parameters(generator, key_size, backend)
def parameters_generator(self): # -> None logger.info('Agreement: CHECK') parameters = dh.generate_parameters(generator=2, key_size=512, backend=default_backend()) # Calcular a privada self.cli_priv_key = parameters.generate_private_key() # Calcular a pública self.cli_pub_key = self.cli_priv_key.public_key() cli_pub_key_bytes = self.cli_pub_key.public_bytes( serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo) # Primos p = parameters.parameter_numbers().p g = parameters.parameter_numbers().g message = { 'type': 'PARAMETERS_GENERATOR', 'cli_pub_key': base64.b64encode(cli_pub_key_bytes).decode('utf-8'), 'p': p, 'g': g, } # Define o state como open, aka vai começar a enviar files # Sinto que isto n deve estar aqui mas ok, talvez ate deva, o problema é # quando for preciso trocar a cifra, adiante, ele envia a sua chave e a seguir # quando receber a proxima mensagem ja é envia files bota e vira self.state = STATE_OPEN self._send(message)
def generate_dh_params(): print('Generating dh parameters') params = dh.generate_parameters(generator=2, key_size=1024, backend=default_backend()) print('Parameters have been generated, Server is ready for requests ...') return params
def test_parameter_bytes_invalid_encoding(self, backend): parameters = dh.generate_parameters(2, 512, backend) with pytest.raises(TypeError): parameters.parameter_bytes( "notencoding", serialization.ParameterFormat.PKCS3 )
def test_parameter_bytes(self, backend, encoding, loader_func): parameters = dh.generate_parameters(2, 512, backend) serialized = parameters.parameter_bytes( encoding, serialization.ParameterFormat.PKCS3) loaded_key = loader_func(serialized, backend) loaded_param_num = loaded_key.parameter_numbers() assert loaded_param_num == parameters.parameter_numbers()
def test_parameter_bytes_invalid_format(self, backend): parameters = dh.generate_parameters(2, 512, backend) with pytest.raises(ValueError): parameters.parameter_bytes( serialization.Encoding.PEM, "notformat" )
def dhke(): print("Generating some numbers, please wait for a sec...") sys.stdout.flush() params = dh.generate_parameters(generator=2, key_size=512, backend=default_backend()) sk = params.generate_private_key() p = sk.public_key().public_numbers().parameter_numbers.p y = sk.public_key().public_numbers().y print( "Let's use the following modulus for our key exchange, using generator g=2:" ) print(p) print("I have generated my public key as follows:") print(y) print("Please enter your public key!") try: x = int(input()) except ValueError: print("You didn't enter an integer for your key! Quitting!") sys.exit() if x < 2 or x >= p: print("Hey! Public keys within range only!") sys.exit() if is_power_of_two(x): print( "Hey! Your exponent (private key) is so small I could've guessed it! Try to use a larger secure exponent instead!" ) sys.exit() pn = dh.DHParameterNumbers(p, 2) peer = dh.DHPublicNumbers(x, params.parameter_numbers()).public_key( default_backend()) global key # lazy key = sk.exchange(peer)
def test_parameter_bytes_openssh_unsupported(self, backend): parameters = dh.generate_parameters(2, 512, backend) with pytest.raises(TypeError): parameters.parameter_bytes( serialization.Encoding.OpenSSH, serialization.ParameterFormat.PKCS3 )
def test_private_bytes_unsupported_encryption_type(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, DummyKeySerializationEncryption())
def test_private_bytes_traditional_openssl_invalid(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption())
def dhParameters(): """ Generates parameters G and P for DH """ parameters = dh.generate_parameters( generator=5, \ key_size=512, backend=default_backend() ) return parameters
def __init__(self): # This example DH server uses a known safe prime, or can generate its own if the PEM file is not available. # The safe prime used here is ffdhe2048, described here: # https://tools.ietf.org/html/rfc7919#appendix-A.1 # There is nothing strictly wrong with generating your own prime, but this one is well tested. import os.path pem_path = os.path.join(os.path.dirname(__file__), 'dh_params.pem') if not os.path.isfile(pem_path): # No PEM file available, generate a new prime of 2048 bits. parameters = dh.generate_parameters(generator=2, key_size=2048, backend=default_backend()) s = parameters.parameter_bytes(Encoding.PEM, ParameterFormat.PKCS3) with open('dh_params.pem', 'wb') as outfile: outfile.write(s) else: # Load PEM file - a standard format for cryptographic keys and numbers. from cryptography.hazmat.primitives.serialization import load_pem_parameters with open(pem_path, 'r') as f: pem_data = f.read().encode("UTF-8") parameters = load_pem_parameters(data=pem_data, backend=default_backend()) self.parameters = parameters self.shared_key = None
def test_public_bytes_invalid_encoding(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key().public_key() with pytest.raises(TypeError): key.public_bytes( "notencoding", serialization.PublicFormat.SubjectPublicKeyInfo )
def dh_generate_parameters(key_size=1024): # Generate some parameters parameters = dh.generate_parameters(generator=2, key_size=key_size) parameter_numbers = parameters.parameter_numbers() p = parameter_numbers.p g = parameter_numbers.g return [p, g]
def __init__(self): self.shared_key = None self.public_key = None self.private_key = None self.dh_parameters = dh.generate_parameters( generator=2, key_size=2048, backend=default_backend()).parameter_bytes(Encoding.DER, ParameterFormat.PKCS3)
def generate_modulus(size=512): parameters = dh.generate_parameters(generator=DH_G, key_size=size, backend=default_backend()) private_key = parameters.generate_private_key() public_key = private_key.public_key() p = public_key.public_numbers().parameter_numbers.p return p
def _generate_diffie_hellman(name, key_size): """ https://stackoverflow.com/questions/39534456/how-to-generate-diffie-hellman-parameters-in-python """ DHBackend.generate_dh_parameters(backend, generator=2, key_size=key_size) dh_parameters = dh.generate_parameters(generator=2, key_size=key_size, backend=backend) with open('{}.pem'.format(name), 'wb') as output: output.write(dh_parameters.parameter_bytes(Encoding.PEM, ParameterFormat.PKCS3))
def test_parameter_bytes(self, backend, encoding, loader_func): parameters = dh.generate_parameters(2, 512, backend) serialized = parameters.parameter_bytes( encoding, serialization.ParameterFormat.PKCS3 ) loaded_key = loader_func(serialized, backend) loaded_param_num = loaded_key.parameter_numbers() assert loaded_param_num == parameters.parameter_numbers()
def test_private_bytes_unsupported_encryption_type(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, DummyKeySerializationEncryption() )
def test_private_bytes_invalid_format(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, "invalidformat", serialization.NoEncryption() )
def test_private_bytes_invalid_encryption_algorithm(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, "notanencalg" )
def test_private_bytes_traditional_openssl_invalid(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption() )
def test_private_bytes_invalid_encoding(self, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(TypeError): key.private_bytes( "notencoding", serialization.PrivateFormat.PKCS8, serialization.NoEncryption() )
def generate(self): parameters = dh.generate_parameters(generator=2, key_size=self.key_size, backend=default_backend()) self._private_key = parameters.generate_private_key() self._public_key = self._private_key.public_key() pn = parameters.parameter_numbers() self._pr = pn.p self._g = pn.g
def create_dhparam(key_size=2048): from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import dh parameters = dh.generate_parameters(generator=2, key_size=key_size, backend=default_backend()) return parameters.parameter_bytes( serialization.Encoding.PEM, format=serialization.ParameterFormat.PKCS3)
def genDH(path, size=2048, public_exponent=65537): #return True if not os.path.exists(path): parametres = dh.generate_parameters(generator=2, key_size=2048, backend=default_backend()) saveDHPem(parametres, path) return True
def test_public_bytes(self, backend, encoding, loader_func): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key().public_key() serialized = key.public_bytes( encoding, serialization.PublicFormat.SubjectPublicKeyInfo) loaded_key = loader_func(serialized, backend) loaded_pub_num = loaded_key.public_numbers() pub_num = key.public_numbers() assert loaded_pub_num == pub_num
def diffie_hellman_init(self): logger.debug("Init Diffie-Hellman") self.parameters = dh.generate_parameters(generator=2, key_size=1024, backend=default_backend()) parameter_numbers = self.parameters.parameter_numbers() # msg = { 'type' : 'DH_INIT', 'data' : { 'params' : parameters.parameter_bytes(Encoding.PEM, ParameterFormat.PKCS3).decode() }} msg = { 'type' : 'DH_INIT', 'data' : { 'p' : parameter_numbers.p, 'g' : parameter_numbers.g }} self._send(msg) return True
def test_public_bytes(self, backend, encoding, loader_func): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key().public_key() serialized = key.public_bytes( encoding, serialization.PublicFormat.SubjectPublicKeyInfo ) loaded_key = loader_func(serialized, backend) loaded_pub_num = loaded_key.public_numbers() pub_num = key.public_numbers() assert loaded_pub_num == pub_num
def test_private_bytes_unencrypted(self, backend, encoding, loader_func): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() serialized = key.private_bytes( encoding, serialization.PrivateFormat.PKCS8, serialization.NoEncryption() ) loaded_key = loader_func(serialized, None, backend) loaded_priv_num = loaded_key.private_numbers() priv_num = key.private_numbers() assert loaded_priv_num == priv_num
def test_exchange(self, backend): parameters = dh.generate_parameters(2, 512, backend) assert isinstance(parameters, dh.DHParameters) key1 = parameters.generate_private_key() key2 = parameters.generate_private_key() symkey1 = key1.exchange(key2.public_key()) assert symkey1 assert len(symkey1) == 512 // 8 symkey2 = key2.exchange(key1.public_key()) assert symkey1 == symkey2
def test_exchange_algorithm(self, backend): parameters = dh.generate_parameters(2, 512, backend) key1 = parameters.generate_private_key() key2 = parameters.generate_private_key() shared_key_bytes = key2.exchange(key1.public_key()) symkey = int_from_bytes(shared_key_bytes, 'big') symkey_manual = pow(key1.public_key().public_numbers().y, key2.private_numbers().x, parameters.parameter_numbers().p) assert symkey == symkey_manual
def test_generate_dh(self, backend, with_q): if with_q: vector = load_vectors_from_file( os.path.join("asymmetric", "DH", "RFC5114.txt"), load_nist_vectors)[0] p = int(vector["p"], 16) g = int(vector["g"], 16) q = int(vector["q"], 16) parameters = dh.DHParameterNumbers(p, g, q).parameters(backend) key_size = 1024 else: generator = 2 key_size = 512 parameters = dh.generate_parameters(generator, key_size, backend) assert isinstance(parameters, dh.DHParameters) key = parameters.generate_private_key() assert isinstance(key, dh.DHPrivateKey) assert key.key_size == key_size public = key.public_key() assert isinstance(public, dh.DHPublicKey) assert public.key_size == key_size assert isinstance(parameters, dh.DHParametersWithSerialization) parameter_numbers = parameters.parameter_numbers() assert isinstance(parameter_numbers, dh.DHParameterNumbers) assert bit_length(parameter_numbers.p) == key_size assert isinstance(public, dh.DHPublicKeyWithSerialization) assert isinstance(public.public_numbers(), dh.DHPublicNumbers) assert isinstance(public.parameters(), dh.DHParameters) assert isinstance(key, dh.DHPrivateKeyWithSerialization) assert isinstance(key.private_numbers(), dh.DHPrivateNumbers) assert isinstance(key.parameters(), dh.DHParameters)
def establish_association(endpoint, assoc_type, session_type, generator, generate_modulus): """Actually establish the association.""" generator = int(generator) if generate_modulus: parameters = generate_parameters(generator=generator, key_size=2048, backend=default_backend()) parameter_numbers = parameters.parameter_numbers() else: parameter_numbers = DHParameterNumbers(DEFAULT_DH_MODULUS, generator) parameters = parameter_numbers.parameters(default_backend()) private_key = parameters.generate_private_key() public_key = int_to_base64(private_key.public_key().public_numbers().y) logging.debug("Private key: %s", private_key.private_numbers().x) logging.debug("Public key: %s", private_key.public_key().public_numbers().y) data = {'openid.ns': OPENID2_NS, 'openid.mode': 'associate', 'openid.assoc_type': assoc_type, 'openid.session_type': session_type, 'openid.dh_consumer_public': public_key} if parameter_numbers != DHParameterNumbers(DEFAULT_DH_MODULUS, DEFAULT_DH_GENERATOR): data['openid.dh_modulus'] = int_to_base64(parameter_numbers.p) data['openid.dh_gen'] = int_to_base64(parameter_numbers.g) logging.info("Query arguments: %s", data) response = requests.post(endpoint, data=data) if response.status_code != 200: if response.status_code == 400: # Is it an error response? error_data = parse_kv_response(response) if error_data.get('mode') == 'error': # It's an error response raise ValueError("Server responded with error: {}".format(error_data.get('error'))) raise ValueError("Response returned incorrect status code: {}".format(response.status_code)) association_data = parse_association_response(response) logging.debug("Association data: %s", association_data) if association_data['assoc_type'] != assoc_type: raise ValueError( "Unexpected assoc_type returned {}, expected {}".format(association_data['assoc_type'], assoc_type)) if association_data['session_type'] != session_type: raise ValueError( "Unexpected session_type returned {}, expected {}".format(association_data['session_type'], session_type)) server_public_key = base64_to_int(association_data['dh_server_public']) shared_secret = private_key.exchange( DHPublicNumbers(server_public_key, parameter_numbers).public_key(default_backend())) # Not an ordinary DH secret is used here. # According to http://openid.net/specs/openid-authentication-2_0.html#rfc.section.8.2.3, the first bit of # the DH secret must be zero. If it isn't, the bytes must be prepended by zero byte before they're hashed. shared_secret = bytearray(shared_secret) if shared_secret[0] > 127: shared_secret = bytearray([0]) + shared_secret shared_secret = bytes(shared_secret) logging.debug("DH shared secret: %s", base64.b64encode(shared_secret)) algorithm = getattr(hashes, assoc_type[5:]) digest = hashes.Hash(algorithm(), backend=default_backend()) digest.update(shared_secret) hashed_dh_shared = digest.finalize() mac_key = strxor(base64.b64decode(association_data['enc_mac_key']), hashed_dh_shared) return {'assoc_type': association_data['assoc_type'], 'session_type': association_data['session_type'], 'assoc_handle': association_data['assoc_handle'], 'expires_in': association_data['expires_in'], 'mac_key': base64.b64encode(mac_key).decode('utf-8')}
def p2p(sock, client_server_ip, client_server_port, settings, cmd_splited, USER_TABLE): server_ip = settings.server_ip server_port = settings.server_port enc = HaoEncryptor(None, None) dec = HaoDecryptor(None, None) # in clear msg1 = Message(MessageType.chat_request) msg1.msg_number = 1 msg1.iv = os.urandom(16) # in cipher n1 = generate_nounce() send_to_client_name = cmd_splited[1] msg1_body = pickle.dumps((n1, send_to_client_name)) msg1.cipher = enc.symmetric_encryption(settings.session_key, msg1.iv, msg1_body) sock.sendto(pickle.dumps(msg1),(server_ip, server_port)) #---------------------------------------------------------MESSAGE 2(RECEIVE) received_data, received_addr = sock.recvfrom(8192) p2p_msg_2 = pickle.loads(received_data) if p2p_msg_2.type == MessageType.chat_request and p2p_msg_2.msg_number == 2: msg2_body_stream = dec.symmetric_decryption(settings.session_key, p2p_msg_2.iv, p2p_msg_2.cipher) msg2_body = pickle.loads(msg2_body_stream) n1s = msg2_body[0] talk_to = msg2_body[1] talk_to_ip = msg2_body[2] talk_to_port = msg2_body[3] talk_to_pub_key_pem = msg2_body[4] # ticket to Bob ticket_to_bob = msg2_body[5] # save the ip and port newClient = ClientItem() newClient.username = talk_to newClient.ip = talk_to_ip newClient.port_listen = talk_to_port newClient.pub_key_pem = talk_to_pub_key_pem #------------------------------------------------------------------------MESSAGE 3(SEND) if n1 == n1s: # msg 3: g^a % p, N4, ticket to bob = {"Alice", Apub, IP, port} msg3 = Message(MessageType.chat_request) msg3.msg_number = 3 msg3.iv_for_bob = p2p_msg_2.iv_for_bob dh_parameters = dh.generate_parameters(generator=2, key_size=512, backend=default_backend()) dh_pri_key = dh_parameters.generate_private_key() settings.dh_pri_key = dh_pri_key dh_pub_key = dh_pri_key.public_key() msg3.dh_g = dh_parameters.parameter_numbers().g msg3.dh_p = dh_parameters.parameter_numbers().p msg3.dh_y = dh_pub_key.public_numbers().y dh_params = (msg3.dh_g,msg3.dh_p,msg3.dh_y) dh_params_string = pickle.dumps(dh_params) ########################################################################################################## # Signing DH for PFS msg3_signature = settings.encryptor.sign(settings.rsa_pri_key, dh_params_string) msg3.signature = msg3_signature ########################################################################################################## n4 = generate_nounce() newClient.last_nounce = n4 # nouce, ticket to bob msg3.n4 = n4 msg3.ticket = ticket_to_bob # # TODO: actually encrypt it sock.sendto(pickle.dumps(msg3), (talk_to_ip, int(talk_to_port))) received_data, received_addr = sock.recvfrom(4096) p2p_msg_4 = pickle.loads(received_data) if p2p_msg_4.type == MessageType.chat_request and p2p_msg_4.msg_number == 4:#----------------------------------Message 4 Receive ######################################################################################################## # Verify DH for PFS msg4_dh_params = (p2p_msg_4.dh_g, p2p_msg_4.dh_p, p2p_msg_4.dh_y) msg4_dh_params_string = pickle.dumps(msg4_dh_params) sign_pub_key = serialization.load_pem_public_key(talk_to_pub_key_pem, backend=default_backend()) verification_result = settings.decryptor.verify_signature(sign_pub_key, p2p_msg_4.signature, msg4_dh_params_string) ######################################################################################################## if verification_result: c_pn = dh.DHParameterNumbers(p2p_msg_4.dh_p, p2p_msg_4.dh_g) c_parameters = c_pn.parameters(default_backend()) c_peer_public_numbers = dh.DHPublicNumbers(p2p_msg_4.dh_y, c_pn) c_peer_public_key = c_peer_public_numbers.public_key(default_backend()) session_key_ab = settings.dh_pri_key.exchange(c_peer_public_key) digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest.update(session_key_ab) digest_c_session_key = digest.finalize() newClient.session_key = digest_c_session_key #Alice Decryptes Nounces n4 and n5 decryptor = HaoDecryptor(None,None) nounce_string = decryptor.symmetric_decryption(digest_c_session_key,p2p_msg_4.iv,p2p_msg_4.nounce_cipher) nounces = pickle.loads(nounce_string) n4_check = nounces[0] n5 = nounces[1] # print ("this is what I got from BOB as my N4") # print n4_check # Alice authenticates Bob if newClient.last_nounce == n4_check:#-------------------------------------------------------------------Message 5 Send iv = os.urandom(16) encryptor = HaoEncryptor(None, None) n5_cipher = encryptor.symmetric_encryption(digest_c_session_key,iv,n5) p2p_msg_5 = Message(MessageType.chat_request) p2p_msg_5.msg_number = 5 p2p_msg_5.cipher = n5_cipher p2p_msg_5.iv = iv sock.sendto(pickle.dumps(p2p_msg_5), received_addr) else: print "Client sent wrong response to the challenge" return newClient else: print "Signature wrong closing connection!"
def create_dhparam(key_size=2048): from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import dh parameters = dh.generate_parameters(generator=2, key_size=key_size,backend=default_backend()) return parameters.parameter_bytes(serialization.Encoding.PEM,format=serialization.ParameterFormat.PKCS3)
def test_private_bytes_rejects_raw(self, encoding, fmt, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key() with pytest.raises(ValueError): key.private_bytes(encoding, fmt, serialization.NoEncryption())
def test_public_bytes_rejects_raw(self, encoding, fmt, backend): parameters = dh.generate_parameters(2, 512, backend) key = parameters.generate_private_key().public_key() with pytest.raises(ValueError): key.public_bytes(encoding, fmt)
def login(sock, client_server_ip, client_server_port, settings): server_ip = settings.server_ip server_port = settings.server_port username = raw_input("Username: "******"Username: "******"login", Apub # 1.1. generate RSA key pairs for communication # sign in message contains: # 1. username # 2. client's ip, port # 3. client's public key # msg 1: send "login", Apub signin_msg_1 = Message(MessageType.signin) signin_msg_1.msg_number = 1 signin_msg_1.client_pub_key = settings.rsa_pub_key_str # sign msg 1 msg_1_stream = pickle.dumps(signin_msg_1) sock.sendto(msg_1_stream, (server_ip, server_port)) received_data, received_addr = sock.recvfrom(4096) # msg 2: reply from server for msg 1 signin_msg_2 = pickle.loads(received_data) if signin_msg_2.type == MessageType.signin and signin_msg_2.msg_number == 2: # sign in message 3: C, [{username, N1, dh_pub_key}s]A signin_msg_3 = Message(MessageType.signin) signin_msg_3.msg_number = 3 # generate a private key for DH key exchange dh_parameters = dh.generate_parameters(generator=2, key_size=1024, backend=default_backend()) dh_pri_key = dh_parameters.generate_private_key() dh_pub_key = dh_pri_key.public_key() # [{username, N1, 2^a mod p}s]A n1 = random.randint(0, 100000000) settings.server_pub_key = serialization.load_pem_public_key(settings.rsa_pub_key_str, backend=default_backend()) # msg 3 cipher: username, N1 signin_msg_3.cipher = settings.encryptor.asymmetric_encryption(pickle.dumps((username, n1)), settings.server_rsa_pub_key) signin_msg_3.cookie = signin_msg_2.cookie # DH key exchange # the server needs g, p, y to generate the shared key # p, g -> DHParameterNumbers # DHParameterNumbers, y -> peer_public_number -> peer_public_key # server_private_key, peer_public_key -> shared_key signin_msg_3.dh_g = dh_parameters.parameter_numbers().g signin_msg_3.dh_p = dh_parameters.parameter_numbers().p signin_msg_3.dh_y = dh_pub_key.public_numbers().y msg_3_stream = pickle.dumps(signin_msg_3.cookie + username + str(n1) + str(signin_msg_3.dh_g) + str(signin_msg_3.dh_p) + str(signin_msg_3.dh_y)) msg_3_signature = settings.encryptor.sign(settings.rsa_pri_key, msg_3_stream) signin_msg_3.signature = msg_3_signature sock.sendto(pickle.dumps(signin_msg_3), (server_ip, server_port)) ############################################################################################### # Client receive msg 4, calculate DH session key received_data, received_addr = sock.recvfrom(4096) signin_msg_4 = pickle.loads(received_data) if signin_msg_4.type == MessageType.signin and signin_msg_4.msg_number == 4: # sign in message 4: [dh_pub_key, Kas{N1+1, N2}, hash(2^as %p, 2^SW % p)]s ############################################################################################### # TODO : verify message 4 verification_result = settings.decryptor.verify_signature(settings.server_rsa_pub_key, signin_msg_4.signature, bin(signin_msg_4.dh_y)) if not verification_result: raise("Message 4 signature not match") return None ############################################################################################### c_pn = dh.DHParameterNumbers(dh_parameters.parameter_numbers().p, dh_parameters.parameter_numbers().g) c_peer_public_numbers = dh.DHPublicNumbers(signin_msg_4.dh_y, c_pn) c_peer_public_key = c_peer_public_numbers.public_key(default_backend()) c_shared_key = dh_pri_key.exchange(c_peer_public_key) digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest.update(c_shared_key) digest_c_shared_key = digest.finalize() if not digest_c_shared_key == signin_msg_4.hash: print("Sign in Message 4, hashes does not match!") return None settings.session_key = digest_c_shared_key nounces_clear = pickle.loads(settings.decryptor.symmetric_decryption(settings.session_key, signin_msg_4.iv, signin_msg_4.cipher)) if nounces_clear[0] != n1+1: print("Incorrect nounce") raise("Incorrect nounce in login message 4") return n2 = nounces_clear[1] ############################################################################################### # sign in message 5: [Kas{N2+1}, hash(2^as % p, 2^sw % p)]A signin_msg_5 = Message(MessageType.signin) signin_msg_5.msg_number = 5 signin_msg_5.iv = os.urandom(16) pwd_hash = hashlib.sha256(password).hexdigest() msg_clear = pickle.dumps((n2, pwd_hash, digest_c_shared_key, client_server_port)) msg_cipher = settings.encryptor.symmetric_encryption(digest_c_shared_key, signin_msg_5.iv, msg_clear) signin_msg_5.cipher = msg_cipher sock.sendto(pickle.dumps(signin_msg_5), (server_ip, server_port)) ############################################################################################### received_data, received_addr = sock.recvfrom(1024) signin_msg_6 = pickle.loads(received_data) if signin_msg_6 == True: print("{}, you have logged in".format(username)) return settings.session_key else: print("Log in FAILED!") else: print("Log in FAILED!") else: print("Log in FAILED!")
def test_small_key_generate_dh(self, backend): with pytest.raises(ValueError): dh.generate_parameters(2, 511, backend)
def test_unsupported_generator_generate_dh(self, backend): with pytest.raises(ValueError): dh.generate_parameters(7, 512, backend)