Package com.eatthepath.noise
Provides classes and interfaces for performing handshakes and exchanging messages via a Noise protocol. This package covers Noise handshakes and steady-state message transport.
A Noise protocol begins with a handshake (see NoiseHandshake
). During a handshake,
two parties exchange messages containing key material and optional, possibly-encrypted payloads as prescribed by a
chosen handshake pattern (see HandshakePattern
). Once the handshake is complete, parties
exchange an effectively unbounded sequence of encrypted messages via a
NoiseTransport
.
Example
The following example illustrates constructing Noise handshakes and exchanging messages via a steady-state Noise
transport. To begin, we choose a Noise protocol (in this case, Noise_NN_25519_ChaChaPoly_SHA256
, which
specifies an NN handshake pattern, an X25519 key agreement algorithm, a ChaCha20-Poly1305 cipher, and a
SHA-256 hash). Then, we construct a pair of handshake objects. In most practical scenarios, the two "ends" of a
handshake are likely to be controlled by different processes (e.g. a client and server), but for this example, we
control both.
final String noiseProtocolName = "Noise_NN_25519_ChaChaPoly_SHA256";
final NoiseHandshake initiatorHandshake =
new NamedProtocolHandshakeBuilder(noiseProtocolName, NoiseHandshake.Role.INITIATOR).build();
final NoiseHandshake responderHandshake =
new NamedProtocolHandshakeBuilder(noiseProtocolName, NoiseHandshake.Role.RESPONDER).build();
Note that in this case, we construct the handshake objects by providing a full Noise protocol name to a
NamedProtocolHandshakeBuilder
. For more complex handshake patterns, callers would be
responsible for providing any keys required for the handshake. Callers may wish to use
NoiseHandshakeBuilder
for more complex handshake patterns, since its static initializer
methods provide compile-time assurances that the correct key material is provided for the chosen handshake pattern
and role.
The NN handshake pattern is defined as:
NN: -> e <- e, ee
To carry out the handshake, we pass messages between the initiator and responder handshakes for each message pattern in the handshake pattern. In the case of an NN handshake pattern, the initiator sends its ephemeral key to the responder. The responder receives and processes the ephemeral key message, then sends its own ephemeral key to the initiator and performs a DH key agreement operation between the two ephemeral keys. The initiator receives the responder's ephemeral key and performs the same key agreement operation.
// -> e (with no additional payload)
final byte[] eMessage = initiatorHandshake.writeMessage((byte[]) null);
responderHandshake.readMessage(eMessage);
// <- e, ee (with no additional payload)
final byte[] eEeMessage = responderHandshake.writeMessage((byte[]) null);
initiatorHandshake.readMessage(eEeMessage);
// At this point, the handshake is finished, and we can "split" the handshake into a Noise transport
assert initiatorHandshake.isDone();
assert responderHandshake.isDone();
With the handshake finished, the handshake objects can be "split" (in the terminology of the Noise protocol) into steady-state transport channels, and then messages can be passed between the initiator and responder at will.
final NoiseTransport initiatorTransport = initiatorHandshake.toTransport();
final NoiseTransport responderTransport = responderHandshake.toTransport();
final byte[] plaintext = "Hello, world!".getBytes(StandardCharsets.UTF_8);
final byte[] ciphertext = initiatorTransport.writeMessage(plaintext);
final byte[] decryptedPlaintext = responderTransport.readMessage(ciphertext);
assert Arrays.equals(plaintext, decryptedPlaintext);
- See Also:
-
ClassDescriptionA
NamedProtocolHandshakeBuilder
constructsNoiseHandshake
instances given a full Noise protocol name and a role (initiator or responder).ANoiseHandshake
instance is responsible for encrypting and decrypting the messages that comprise a Noise handshake.An enumeration of roles within a Noise handshake.A Noise handshake builder constructsNoiseHandshake
instances with known handshake patterns and roles.A Noise transport is an interactive reader and writer of Noise transport messages.A Noise transport reader decrypts Noise transport messages.A Noise transport writer encrypts Noise transport messages.Indicates that a named pattern is not a recognized fundamental or deferred Noise handshake pattern and cannot be derived by modifying a recognized fundamental or deferred Noise handshake pattern.