mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
docs: Update secure-p2p doc to match the spec + current implementation
Closes #2421. I am of the opinion that the spec is easier to read than this though, and we shouldn't really explain this here other than that we use a variant of station to station protocol, with X25519 for the diffie hellman, and we describe the related security properties.
This commit is contained in:
parent
8aad09d9d4
commit
f76312ffe6
@ -8,41 +8,43 @@ Each peer generates an ED25519 key-pair to use as a persistent
|
|||||||
(long-term) id.
|
(long-term) id.
|
||||||
|
|
||||||
When two peers establish a TCP connection, they first each generate an
|
When two peers establish a TCP connection, they first each generate an
|
||||||
ephemeral ED25519 key-pair to use for this session, and send each other
|
ephemeral X25519 key-pair to use for this session, and send each other
|
||||||
their respective ephemeral public keys. This happens in the clear.
|
their respective ephemeral public keys. This happens in the clear.
|
||||||
|
|
||||||
They then each compute the shared secret. The shared secret is the
|
They then each compute the shared secret, as done in a [diffie hellman
|
||||||
multiplication of the peer's ephemeral private key by the other peer's
|
key exhange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange).
|
||||||
ephemeral public key. The result is the same for both peers by the magic
|
The shared secret is used as the symmetric key for the encryption algorithm.
|
||||||
of [elliptic
|
|
||||||
curves](https://en.wikipedia.org/wiki/Elliptic_curve_cryptography). The
|
|
||||||
shared secret is used as the symmetric key for the encryption algorithm.
|
|
||||||
|
|
||||||
The two ephemeral public keys are sorted to establish a canonical order.
|
We then run [hkdf-sha256](https://en.wikipedia.org/wiki/HKDF) to expand the
|
||||||
Then a 24-byte nonce is generated by concatenating the public keys and
|
shared secret to generate a symmetric key for sending data,
|
||||||
hashing them with Ripemd160. Note Ripemd160 produces 20byte hashes, so
|
a symmetric key for receiving data,
|
||||||
the nonce ends with four 0s.
|
a challenge to authenticate the other party.
|
||||||
|
One peer will send data with their sending key, and the other peer
|
||||||
|
would decode it using their own receiving key.
|
||||||
|
We must ensure that both parties don't try to use the same key as the sending
|
||||||
|
key, and the same key as the receiving key, as in that case nothing can be
|
||||||
|
decoded.
|
||||||
|
To ensure this, the peer with the canonically smaller ephemeral pubkey
|
||||||
|
uses the first key as their receiving key, and the second key as their sending key.
|
||||||
|
If the peer has the canonically larger ephemeral pubkey, they do the reverse.
|
||||||
|
|
||||||
The nonce is used to seed the encryption - it is critical that the same
|
Each peer also keeps a received message counter and sent message counter, both
|
||||||
nonce never be used twice with the same private key. For convenience,
|
are initialized to zero.
|
||||||
the last bit of the nonce is flipped, giving us two nonces: one for
|
All future communication is encrypted using chacha20poly1305.
|
||||||
encrypting our own messages, one for decrypting our peer's. Which ever
|
The key used to send the message is the sending key, and the key used to decode
|
||||||
peer has the higher public key uses the "bit-flipped" nonce for
|
the message is the receiving key.
|
||||||
encryption.
|
The nonce for chacha20poly1305 is the relevant message counter.
|
||||||
|
It is critical that the message counter is incremented every time you send a
|
||||||
|
message and every time you receive a message that decodes correctly.
|
||||||
|
|
||||||
Now, a challenge is generated by concatenating the ephemeral public keys
|
Each peer now signs the challenge with their persistent private key, and
|
||||||
and taking the SHA256 hash.
|
|
||||||
|
|
||||||
Each peer signs the challenge with their persistent private key, and
|
|
||||||
sends the other peer an AuthSigMsg, containing their persistent public
|
sends the other peer an AuthSigMsg, containing their persistent public
|
||||||
key and the signature. On receiving an AuthSigMsg, the peer verifies the
|
key and the signature. On receiving an AuthSigMsg, the peer verifies the
|
||||||
signature.
|
signature.
|
||||||
|
|
||||||
The peers are now authenticated.
|
The peers are now authenticated.
|
||||||
|
|
||||||
All future communications can now be encrypted using the shared secret
|
The communication maintains Perfect Forward Secrecy, as
|
||||||
and the generated nonces, where each nonce is incremented by one each
|
|
||||||
time it is used. The communications maintain Perfect Forward Secrecy, as
|
|
||||||
the persistent key pair was not used for generating secrets - only for
|
the persistent key pair was not used for generating secrets - only for
|
||||||
authenticating.
|
authenticating.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user