def decrypt_X25519_Chacha20_Poly1305(encrypted_part, privkey, sender_pubkey=None): #LOG.debug('----------- Encrypted data: %s', encrypted_part.hex()) LOG.debug(' my secret key: %s', privkey.hex()) LOG.debug('Sender public key: %s', sender_pubkey.hex() if sender_pubkey else None) peer_pubkey = encrypted_part[:32] if sender_pubkey and sender_pubkey != peer_pubkey: raise ValueError("Invalid Peer's Public Key") nonce = encrypted_part[32:44] packet_data = encrypted_part[44:] LOG.debug(' peer pubkey: %s', peer_pubkey.hex()) LOG.debug(' nonce: %s', nonce.hex()) LOG.debug('encrypted data: %s', packet_data.hex()) # X25519 shared key pubkey = bytes( PrivateKey(privkey).public_key) # slightly inefficient, but working shared_key, _ = crypto_kx_client_session_keys(pubkey, privkey, peer_pubkey) LOG.debug('shared key: %s', shared_key.hex()) # Chacha20_Poly1305 return crypto_aead_chacha20poly1305_ietf_decrypt(packet_data, None, nonce, shared_key) # no add
def test_crypto_kx_session_keys(seed1, seed2): s_keys = b.crypto_kx_seed_keypair(seed1) c_keys = b.crypto_kx_seed_keypair(seed2) server_rx_key, server_tx_key = \ b.crypto_kx_server_session_keys(s_keys[0], s_keys[1], c_keys[0]) client_rx_key, client_tx_key = \ b.crypto_kx_client_session_keys(c_keys[0], c_keys[1], s_keys[0]) assert client_rx_key == server_tx_key assert server_rx_key == client_tx_key
def test_crypto_kx_session_keys(seed1, seed2): s_keys = b.crypto_kx_seed_keypair(seed1) c_keys = b.crypto_kx_seed_keypair(seed2) server_rx_key, server_tx_key = b.crypto_kx_server_session_keys( s_keys[0], s_keys[1], c_keys[0]) client_rx_key, client_tx_key = b.crypto_kx_client_session_keys( c_keys[0], c_keys[1], s_keys[0]) assert client_rx_key == server_tx_key assert server_rx_key == client_tx_key
def keyexchange(n, ip, publickey_list, secretkey_list, extra_list): exchangeKey = [] for i in range(n): if i == ip: exchangeKey.append(0) else: if i > ip: comKeyint, _ = xc.crypto_kx_client_session_keys(publickey_list[i], secretkey_list[i], extra_list[i]) else: _, comKeyint = xc.crypto_kx_server_session_keys(publickey_list[i], secretkey_list[i], extra_list[i]) exchangekey = int.from_bytes(xc.crypto_hash_sha256(comKeyint), byteorder='big') exchangeKey.append(exchangekey) return exchangeKey
async def initialize(self, server_address: str, server_port: int) -> None: """Initialize an NSTP connection.""" if self.reader is not None: raise Exception("session has already been initialized") self.reader, self.writer = await asyncio.open_connection( server_address, server_port) # Send a hello m = NSTPMessage() m.client_hello.major_version = 4 m.client_hello.minor_version = 0 m.client_hello.user_agent = "nstpc" m.client_hello.certificate.CopyFrom(self.client_cert) logging.debug(f"SEND {m}") m_data = m.SerializeToString() self.writer.write(struct.pack(">H", len(m_data))) self.writer.write(m_data) await self.writer.drain() # Receive a hello m = NSTPMessage() m_length = struct.unpack(">H", await self.reader.readexactly(2))[0] m.ParseFromString(await self.reader.readexactly(m_length)) logging.debug(f"RECV {m}") m_type = m.WhichOneof("message_") if m_type != "server_hello": raise Exception(f"expected server hello, received {m_type}") if m.server_hello.major_version != 4: raise Exception( f"invalid server major version {m.server_hello.major_version}") self.verifier.verify_server_certificate(m.server_hello.certificate, server_address) if m.server_hello.HasField("certificate_status"): status = m.server_hello.certificate_status else: status = await self.fetch_certificate_status( m.server_hello.certificate) self.verifier.verify_server_certificate_status( m.server_hello.certificate, status, self.status_server_address) # Establish session keys self.reader_key, self.writer_key = \ crypto_kx_client_session_keys(self.client_cert.encryption_public_key, self.client_key.encryption_private_key, m.server_hello.certificate.encryption_public_key) logging.info("session initialized")
def keyexchange(n, party_i, my_pkey_list, my_skey_list, other_pkey_list): common_key_list = [] for i in range(n): #Generate DH (common) keys if i == party_i: common_key_list.append(0) else: if i > party_i: common_key_raw, _ = nb.crypto_kx_client_session_keys( my_pkey_list[i], my_skey_list[i], other_pkey_list[i]) else: _, common_key_raw = nb.crypto_kx_server_session_keys( my_pkey_list[i], my_skey_list[i], other_pkey_list[i]) #Hash the common keys common_key = int.from_bytes(nb.crypto_hash_sha256(common_key_raw), byteorder='big') common_key_list.append(common_key) return common_key_list
def dict_keyexchange(peer_list, self_id, my_pkeys, my_skeys, peer_pkeys): # CDB: The last three parameters are now all dictionaries. Dictionary keys # are peer ids to which we gave the key, or from which we received the key. # comkeys is also now a dictionary keyed by peer id. comkeys = {} for peer_id in peer_list: if peer_id > self_id: common_key_raw, _ = nb.crypto_kx_client_session_keys( my_pkeys[peer_id], my_skeys[peer_id], peer_pkeys[peer_id]) else: _, common_key_raw = nb.crypto_kx_server_session_keys( my_pkeys[peer_id], my_skeys[peer_id], peer_pkeys[peer_id]) # Hash the common keys. comkeys[peer_id] = int.from_bytes( nb.crypto_hash_sha256(common_key_raw), byteorder='big') return comkeys
def test_crypto_kx_session_wrong_key_lengths(): s_keys = b.crypto_kx_keypair() c_keys = b.crypto_kx_keypair() with pytest.raises(exc.TypeError): b.crypto_kx_server_session_keys(s_keys[0][:-1], s_keys[1], c_keys[0]) with pytest.raises(exc.TypeError): b.crypto_kx_client_session_keys(c_keys[0][:-1], c_keys[1], s_keys[0]) with pytest.raises(exc.TypeError): b.crypto_kx_server_session_keys(s_keys[0], s_keys[1][:-1], c_keys[0]) with pytest.raises(exc.TypeError): b.crypto_kx_client_session_keys(c_keys[0], c_keys[1][:-1], s_keys[0]) with pytest.raises(exc.TypeError): b.crypto_kx_server_session_keys(s_keys[0], s_keys[1], c_keys[0][:-1]) with pytest.raises(exc.TypeError): b.crypto_kx_client_session_keys(c_keys[0], c_keys[1], s_keys[0][:-1])