You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've implemented a new feature that I wanted to request comments on before releasing in the next version of BonsaiDb.
While working on Dossier, I wanted to allow the tool to authenticate using some sort of API token, in a fashion similar to how many authenticated APIs such as S3 work.
The goals of this feature to me were:
Server securely verifies client authentication
Lightweight from a dependencies perspective
I do not need the client to be able to verify the server's authenticity. To me, TLS already does a good job of that. Long term, I have desires for a more diverse set of token-like authentication schemes, and I know @daxpedda has some of his own ideas as well.
In looking at various libraries, I noticed that the BLAKE3 crate had two functions that seemed very useful: keyed hashing and key derivation. These functions are discussed in the BLAKE3 specification.
The approach outlined below is what is coded in the main branch right now, with the caveat that database queries are involved in authentication, and no attempt at amortizing their expenses to a constant time have been made yet (#94).
Glossary
Authentication Token ID: The unique ID of the authentication token.
Authentication Token Secret: The secret token used during authentication. This should never leave the client.
Client Initiates Authentication
The goal of this initial phase is to provide the server enough information to validate that the client has the private token.
The initial request contains a hash computed with the client's current timestamp as nanoseconds:
The client sends this hash, the timestamp, and the token id to the server to begin authentication.
Server Verifies Client Has Token, Issues Challenge
The server is able to verify that the timestamp is reasonable (currently within 10 minutes). If so, the token is retrieved from the database and the hash is computed and compared. Upon success, the server responds with a random sequence of bytes known as the challenge.
The purpose of this phase is to prevent connections from polluting the session map in BonsaiDb. Additionally after #94, this phase will also prevent sniffing for valid token IDs, as the only way to proceed to the next phase is to produce a valid hash.
Client issues challenge response
The client takes the challenge from the server and creates a new hash. The timestamp in this situation is provided by the server. The use of the server's timestamp prevents the same key from being used in keyed_hash() in separate challenge/response invocations.
The client responds with the computed hash, and the server verifies with constant time evaluation that the hash matches the expected result.
At this point, the client now assumes the identity that the token was created for.
Summary
I know that public-key cryptography would be a great solution for this. My issue is that most high-level crates are heavy dependencies. Additionally, I have a preference for some of the newer algorithms that have a colorful maintenance history that lead to out of date dependencies.
When looking at the BLAKE3 paper, it looks like it provides the level of guarantees I'm looking for for this type of authentication. As I'm not a cryptographer, however, I wanted to submit this for comments.
help wantedExtra attention is neededquestionFurther information is requestedmultiuserIssues impacting multi-user support
1 participant
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I've implemented a new feature that I wanted to request comments on before releasing in the next version of BonsaiDb.
While working on Dossier, I wanted to allow the tool to authenticate using some sort of API token, in a fashion similar to how many authenticated APIs such as S3 work.
The goals of this feature to me were:
I do not need the client to be able to verify the server's authenticity. To me, TLS already does a good job of that. Long term, I have desires for a more diverse set of token-like authentication schemes, and I know @daxpedda has some of his own ideas as well.
In looking at various libraries, I noticed that the BLAKE3 crate had two functions that seemed very useful: keyed hashing and key derivation. These functions are discussed in the BLAKE3 specification.
The approach outlined below is what is coded in the main branch right now, with the caveat that database queries are involved in authentication, and no attempt at amortizing their expenses to a constant time have been made yet (#94).
Glossary
Client Initiates Authentication
The goal of this initial phase is to provide the server enough information to validate that the client has the private token.
The initial request contains a hash computed with the client's current timestamp as nanoseconds:
The client sends this hash, the timestamp, and the token id to the server to begin authentication.
Server Verifies Client Has Token, Issues Challenge
The server is able to verify that the timestamp is reasonable (currently within 10 minutes). If so, the token is retrieved from the database and the hash is computed and compared. Upon success, the server responds with a random sequence of bytes known as the challenge.
The purpose of this phase is to prevent connections from polluting the session map in BonsaiDb. Additionally after #94, this phase will also prevent sniffing for valid token IDs, as the only way to proceed to the next phase is to produce a valid hash.
Client issues challenge response
The client takes the challenge from the server and creates a new hash. The timestamp in this situation is provided by the server. The use of the server's timestamp prevents the same key from being used in
keyed_hash()
in separate challenge/response invocations.The client responds with the computed hash, and the server verifies with constant time evaluation that the hash matches the expected result.
At this point, the client now assumes the identity that the token was created for.
Summary
I know that public-key cryptography would be a great solution for this. My issue is that most high-level crates are heavy dependencies. Additionally, I have a preference for some of the newer algorithms that have a colorful maintenance history that lead to out of date dependencies.
When looking at the BLAKE3 paper, it looks like it provides the level of guarantees I'm looking for for this type of authentication. As I'm not a cryptographer, however, I wanted to submit this for comments.
Beta Was this translation helpful? Give feedback.
All reactions