-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement cryptography for laminar #41
Comments
I play with my protocol implementation based on netcode.io 1.02 that uses My (re)implementation of netcode.io has a different header format. Overhead: 18-25(or 24) bytes per payload packet, 19-20 bytes in most cases (16 bytes for Poly1305 and 2-9 bytes for sequence). I saved at least one byte because I can. In fact, I just used the implementation details of the prefix varint. So I got the following format for payload packages:
I think I could prohibit the use of the full 64-bit sequence. 56 bits is enough. This is quite a fun byte counting game. |
@lain-dono really thanks for your input, saying after 2 months :). Cryptography just doesn't have very high prio now. However, I did some research on cryptography and we might use TLS 1.3 on top of laminar. QUIC also uses it for secure communication. TLS 1.3 offers a 0-Roundtrip solution, is safer and more. |
Would like to tackle this if possible. |
I was questioning if TLS is really fitted our purpose. I am thinking this because TLS is asymmetric encryption method. Basically, symmetric encryption fits us very well and is a lot faster, for example, we could use RC4, AES, DES, 3DES, QUAD. |
TLS is only using asymmetric encryption for key exchange or key agreement, cyphers used by TLS are using symmetric encryption. Basically we want to protect against the following "attacks" (rough overview):
Especially things like key exchange are really hard to get right. Using a well established standard is they way to go here I believe. Another part of it is maintenance, not only is encryption, security issues and bugs kept up to date and fixed, but the protocol itself is constantly monitored and improved. |
Have you considered using Noise instead of (D)TLS? It's the protocol used by Wireguard. Noise is much simpler than DTLS, and easy to implement on top of libsodium. You would probably get something close to what @lain-dono has implemented, but with the possibility of an asymmetric handshake. 0-RT is also a possibility. |
That's interesting never heard of it! It could be of use in our scenario as far I can tell. |
@TimonPost I can recommend snow as a nice implementation of the Noise Protocol. |
Wow, it's been two years and the problem is still unexplored. For a start, what problems do we want to solve?
Among other things, you usually want to separate auth-server and game-server. To solve these problems, we need a 3-way handshake and special auth tokens.
The AuthToken (0) contains:
To hide the private parts of the token, I recommend XChaCha20Poly1305. The reason for this is the 192-bit (24-byte) nonce. This allows randomisation to be used to generate nonce. Also RustCrypto/AEADs#1. Rediced-round variations are about 2.5 times faster. The client receives his token from Auth and attempts to perform a handshake based on it. Let's talk about a handshake. The first message (1) can be unencrypted. However, all meaningful data must be protected by AEAD. The server must discard the data first on the basis of the open data. The server then tries to verify an attempt to reuse the token. The server then decrypts the private part. If all is well, the server half-opens the connection and replies with an encrypted message (2). There is an option to explicitly deny a connection to a client (e.g. the server is full). Inside this message is a token that is sent back via the client. Only the server can read this. The client must confirm that it can decrypt messages from the server and is the owner of the IP (protection against ip-spoofing attacks). (3) After receiving (3), the server considers the connection fully open. The client considers the connection open after receiving any payload packet. Messages (1) and (3) are sent by the client with a certain frequency. For example 5-10 times per second. And only 5-10 times. The lifetime of the AuthToken is chosen to be long enough to establish a connection. This is how a scheme based on netcode.io will work. This scheme could be improved in some places, but it already solves all our problems. The only thing I would replace the ChaCha20 with the ChaCha8. Because Too Much Crypto. Great, now let's talk about Noise. The scheme above can be supplemented by some key exchange scheme. I would suggest using either NKpsk0 or NNpsk0. The only difference between them is the presence of a server static public key. If you want to use NKpsk0, this key may be passed to the client along with the AuthToken or hardcoded into the client. The psk is actually transferred via the private part of the AuthToken. I wouldn't recommend using something like snow. Such libraries are designed for the general case. If you hardcode a specific handshake algorithm, it will be faster and more robust. It is also easier to use a non-standard set of cryptographic primitives. ChaCha8Poly1305 as AEAD. Blake3 as hash. However, I have not investigated the Diffie-Hellman key exchange replacement. x25519 is ok. Any questions? |
Note: I implement XChaChaPoly reduced-round. RustCrypto/AEADs#355 |
This library is not actively maintained anymore, unfortunately. Due to some other priorities, I can not focus on implementing, reviewing, and analyzing this feature with you. Feel free to take this issue, implement it and maybe discuss it with others who might be interested in solving this. |
Start with one time padding and DTLS.
The text was updated successfully, but these errors were encountered: