Key Exchange¶
Usage¶
N variant¶
In the N variant key exchange, the client is not authenticated, and the server is authenticated using its public key.
- The server generates a long-term key pair.
- The client knows the server's public key.
- The client generates session keys and sends a packet with an ephemeral public key to the server.
- The server receives the packet and generates the same session keys on its side.
Server side:
=> Printed public key: RvyXqG9WP6nYKQRoIzmnDMvUE5KAnbDNAPXPG8dphi0=
Client side:
from cydrogen import KxPublicKey, client_init_kx_n
server_public_key = KxPublicKey("RvyXqG9WP6nYKQRoIzmnDMvUE5KAnbDNAPXPG8dphi0=")
session_keys, packet = client_init_kx_n(server_public_key)
session_keys contains the session keys that the client would use to communicate with the server.
packet contains the ephemeral public key and other necessary information to complete the key exchange.
The client can now send the packet to the server.
Server side:
session_keys contains the session keys that the server would use to communicate with the client.
They are the same as the ones generated by the client (only the order of keys rx/tx is reversed).
KK variant¶
In the KK variant key exchange, the client and the server authenticate each other using their public keys.
- The client generates a long-term key pair.
- The server generates a long-term key pair.
- The client knows the server's public key, and the server knows the client's public key.
- The client initiates the key exchange by sending a packet with its ephemeral public key to the server.
- The server receives the packet, generates session keys, and sends a packet with its ephemeral public key to the client.
- The client receives the packet and generates the same session keys on its side.
Client side:
from cydrogen import KxPair, KxPublicKey
# client keygen
client_kp = KxPair.gen()
print(client_kp.public_key())
# qkPUJxB+//AFmVb9B40z8lmbh/RK6LyeKLWot57190s=
# client knows server's public key
server_public_key = KxPublicKey("blnFyUVHsJNj9cRGIbhDU04M/Iq7fWL5Aam+IosBQ1s=")
# client initiates key Exchange
s = client_kp.client_init_kx_kk(server_public_key)
# now s.packet1 contains the packet to send to the server
# [client sends s.packet1 to the server]
# [the server will respond with some packet2]
# client calculates session keys
session_keys = s.client_finish_kx_kk(packet2)
Server side:
from cydrogen import KxPair, KxPublicKey
# server keygen
server_kp = KxPair.gen()
print(server_kp.public_key())
# blnFyUVHsJNj9cRGIbhDU04M/Iq7fWL5Aam+IosBQ1s=
# server knows client's public key
client_public_key = KxPublicKey("qkPUJxB+//AFmVb9B40z8lmbh/RK6LyeKLWot57190s=")
# [server receives packet1 from the client]
# the server calculates session keys
session_keys, packet2 = server_kp.server_process_kx_kk(client_public_key, packet1)
# [server sends packet2 to the client]
client_init_kx_n(server_public_key, psk=None)
¶
Initiate a key exchange variant N (anonymous client) from the client side.
Parameters:
-
server_public_key(KxPublicKey) –The public key of the server to exchange keys with.
-
psk(Psk | None, default:None) –An optional pre-shared key to use in the key exchange.
Returns:
-
SessionPair–A tuple containing a SessionPair with the symmetric keys for the session.
-
KX_N_Packet1–The packet to send to the server.
Raises:
-
KeyExchangeException–If the operation fails.
server_finish_kx_n(server_kp, packet1, psk=None)
¶
Finalize a key exchange variant N (anonymous client) from the server side.
Parameters:
-
server_kp(KxPair) –The server key pair.
-
packet1(KX_N_Packet1) –The packet received from the client.
-
psk(Psk | None, default:None) –An optional pre-shared key to use in the key exchange.
Returns:
-
SessionPair–A SessionPair with the symmetric keys for the session.
Raises:
-
KeyExchangeException–If the operation fails. In particular, this exception is raised if the packet is invalid or if the key exchange fails.
class KxPair ¶
KxPair represents a pair of public/secret keys used in key exchange.
KxPair implements the buffer protocol, allowing it to be used as a byte-like object.
__init__(kp)
¶
Initializes a KxPair instance.
Parameters:
Raises:
-
ValueError–If the provided key pair data is invalid.
__str__()
¶
Returns a string representation of the KxPair (base64 encoded).
Returns:
-
str–A base64 encoded string representation of the key pair.
client_init_kx_kk(server_public_key)
¶
Initiate a key exchange variant KK from the client side.
Parameters:
-
server_public_key(KxPublicKey) –The public key of the server to exchange keys with.
Returns:
-
KxKkClientState–A state object containing the first packet to send to the server.
Raises:
-
KeyExchangeException–If the operation fails.
from_keys(public_key, secret_key)
classmethod
¶
Creates a KxPair instance from a public key and a secret key.
Parameters:
-
public_key(KxPublicKey | str | bytes | Buffer) –The public key to use.
-
secret_key(KxSecretKey | str | bytes | Buffer) –The secret key to use.
Returns:
-
Self–A KxPair instance initialized with the provided keys.
Raises:
-
ValueError–If the provided keys are invalid.
gen()
classmethod
¶
Generates a new KxPair instance with a random key pair.
Returns:
-
Self–A new KxPair instance with a randomly generated public and secret key.
public_key()
¶
Returns the public key part of the KxPair.
Returns:
-
KxPublicKey–A KxPublicKey instance representing the public key part of the KxPair.
secret_key()
¶
Returns the secret key part of the KxPair.
Returns:
-
KxSecretKey–A KxSecretKey instance representing the secret key part of the KxPair.
server_finish_kx_n(packet1, psk=None)
¶
server_process_kx_kk(client_public_key, packet1)
¶
Process a key exchange variant KK from the server side.
Parameters:
-
client_public_key(KxPublicKey) –The public key of the client to exchange keys with.
-
packet1(KX_KK_Packet1) –The packet received from the client.
Returns:
-
SessionPair–A SessionPair with the symmetric keys for the session.
-
KX_KK_Packet2–An object representing the packet to send back to the client.
Raises:
-
KeyExchangeException–If the operation fails. In particular, this exception is raised if the packet is invalid or if the key exchange fails.
class KxPublicKey ¶
The KxPublicKey class represents a public key used in key exchange.
KxPublicKey implements the buffer protocol, allowing it to be used as a byte-like object.
__init__(kp)
¶
Initializes a KxPublicKey instance.
Parameters:
Raises:
-
ValueError–If the provided key data is invalid.
class KxSecretKey ¶
The KxSecretKey class represents a secret key used in key exchange.
KxSecretKey implements the buffer protocol, allowing it to be used as a byte-like object.
__init__(kp)
¶
Initializes a KxSecretKey instance.
Parameters:
Raises:
-
ValueError–If the provided key data is invalid.
class SessionPair ¶
The SessionPair class represents a pair of symmetric keys to be used to secure a session with a peer.
Attributes:
-
rx(SecretBoxKey) –The symmetric key used to decrypt messages received from the peer.
-
tx(SecretBoxKey) –The symmetric key used to encrypt messages sent to the peer.
__init__(rx, tx)
¶
Initializes a SessionPair instance.
Parameters:
-
rx(SecretBoxKey) –The symmetric key used to decrypt messages received from the peer.
-
tx(SecretBoxKey) –The symmetric key used to encrypt messages sent to the peer.
class KxKkState ¶
KxKkClientState represents the state of a key exchange variant KK from the client side.
session_pair is initially None and will be set after client_finish_kx_kk is called.
Attributes:
-
packet1(KX_KK_Packet1 | None) –The packet to send to the server as part of the key exchange.
-
session_pair(SessionPair | None) –The session pair containing the symmetric keys for the session.
client_finish_kx_kk(packet2)
¶
Finalizes the key exchange variant KK from the client side.
Parameters:
-
packet2(KX_KK_Packet2) –The packet received from the server.
Returns:
-
Self–The updated state including the session keys.
Raises:
-
KeyExchangeException–If the operation fails. In particular, this exception is raised if the packet is invalid or if the key exchange fails.
class Psk ¶
Bases: BaseKey
The Psk class represents a pre-shared key (PSK).
Pre-shared keys are used optionally by the key exchange algorithms.
__bool__()
¶
Returns True if the key is not zero, False otherwise.
Returns:
-
bool–True if the key is not zero, False otherwise.
__str__()
¶
Returns a base64-encoded representation of the key.
Returns:
-
str–A string representing the key in base64 encoding.
gen()
classmethod
¶
is_zero()
¶
read_from(reader)
classmethod
¶
Create a key from a reader.
Parameters:
-
reader(Reader) –A reader object that supports the read method.
Returns:
-
Self–A new instance of BaseKey read from the provided reader.
Raises:
-
TypeError–If the provided reader does not have a 'read' method.
-
ValueError–If the read data is not 32 bytes long.