From 49f0a2cb240ee22919434ce9fe4aa2d68a863c31 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Thu, 25 Aug 2022 01:34:24 +0200 Subject: [PATCH 1/8] draft: Asymmetric Key Client Authentication --- TEP-asymmetric_key_client_authentication.md | 223 ++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 TEP-asymmetric_key_client_authentication.md diff --git a/TEP-asymmetric_key_client_authentication.md b/TEP-asymmetric_key_client_authentication.md new file mode 100644 index 0000000..1a5c91a --- /dev/null +++ b/TEP-asymmetric_key_client_authentication.md @@ -0,0 +1,223 @@ +|TEP: ????|Asymmetric Key Client Authentication| +|-:|:---| +|__Layer:__|Index| +|__Authors:__|Cameron Garnham| +|__Status:__|Draft| +|__Discussion:__|| +|__Type:__|Standards Track| +|__Created:__|2022-08-22| +|__Updated:__|| +|__Resolution:__|| + +# Introduction + +## Abstract +This document proposes the use of asymmetric cryptography for user accounts and their authentication. + +## Copyright +This document is licensed under the 2-clause BSD license. + +## Motivation +Currently Torrust uses traditional password-username based authentication: + +* For every user the server stores a username, salt, and hashed password. +* To login, the client sends their username and password to the server. +* The server looks up the username and gets the salt, salts and hashes the supplied password, and compares it with the hashed password on record. +* If matching, the client is authenticated as that user. + +Asymmetric authentication has a number of advantages when compared to password authentication, (assuming the client software is honest): +* No need to send any secret data to the server. In contrast, (hashed and salted) passwords that have to be protected from leakage and misuse. +* Synchronization of user-accounts in a group of federated servers becomes much safer: Instead of sharing hashed-passwords between the servers, (or using some centralized authentication service), the servers only need to synchronise the public-keys, without the risk of leaking secert-data. + +The disadvantage: +* The user no longer picks their own password, instead a private key is generated for the user's client software, this key is 32-bytes long and impossible to remember. If the user looses this code, they loose access to their account. + +This disadvantage is mitigated by providing the user with a 'backup seed' when they generate their private key, that the user can use to recover their private key. + +# Design +We first describe the database and user-structure, and general protocols, then we specify clients generating new private keys, and finally describe the public key authentication protocol. + +## Overview +New Users: +1. Client generates secret keys, and derives public key. +2. Client and server preform the Diffie-Hellman authentication protocol. +3. Client creates username, and the public key is associated the username. + +Existing Users: +1. Client and server preform the Diffie-Hellman authentication protocol. +2. Client selects username that it wishes to login with. + +(There may be more than one username that is associated with the same public key). + +## Users +A username is the unique key in the database retaining to the actions of a user. Public keys are associated with users, for a particular purpose. Every public-key-purpose combination has a set of timed status. + +``` +[user] +(PK. String) username + +[purposed_public_key] +(PK. public_key || purpose) +(Enum.) purpose +(Binary.) 32-byte-public_key + +[status_timed] +(PK. Unique Hashed) +(Enum.) status +(Date-Time. Optional.) beginning +(Date-Time. Optional.) end + +[user] many-many [purposed_public_key] + +[user][purposed_public_key] many [status_timed] +``` + +_"Users and Purposed-Public-Keys have a many-many association, each association may associate many timed statuses.":_ +- Each _user_ may look up what _purposed public keys_ it is associated with.
+Likewise, Each _purposed public key_ may look up what _users_ it is associated with. +- Each _(user <> purposed public key)_ link can look up it's associated _timed statuses_. + +### Purposes +In this document we only user the `A` for "Authentication".
In the future we may propose additional purposes. +``` +Purposes (enum): + +A: Authentication +``` + +### Status Validity +If revocation does not specify a beginning, it is for all time periods.
+`Active` has the lowest priority: The key must be `created`, and not `expired`, and not `revoked`. +``` +Status (enum): + +A: Active +C: Created +E: Expired +R: Revoked +``` +#### Status Validity Table: +|status|beginning|end| +|:-|:-|:-| +|active|must|must| +|created|must|none| +|expired|must|none| +|revoked|optional|none| + +# Specification +The server maintains a list of public keys that may be used for authentication for each user. A user may propose a new public key be added to their list of authentication keys, or may revoke or expire an existing key. + +* To add, or expire, or increase the active period a public key, the user must first authenticate with this new key to prove ownership. +* To revoke, the user doesn't need to authenticate with that key. (However some other form of checks should be preformed, such as verification by a moderator.) + +Users who do not have any public key associated, for example new users, or when transitioning from password based authentication should first authenticate with their public key, then preform the association with the user account. + +## Mnemonic Codes +Clients generate a mnemonic code according to: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). + +The seed words are prefixed with an additional `"torrust"` word, and displayed to the user. The 'torrust' seed word is not included in the checksum calculation, however must be present when the user enters their seed in recovery. + +Clients must provide an option for the user to give a seed-password in generation and recovery. + +* The client should only need their seed mnemonic code in the case they have lost their other login credentials. + +## Public and Private Key Derivation +Deriving the keys according to: [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). + +We use the following hardened derivation path:
The index is increased in the case the user has rotated their keys, for the moment we only use zero: +``` +m / purpose' / version' / torrust-purpose' / index' + +m / "torrust" / 0 / "authentication" / 0 +``` +The resulting node is a private-public secp256k1 key-pair. + +## Login Credential Encoding +For encoding the secp256k1, we use [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) encoding, 32-bytes for public keys.
+For displaying the login credentials, we use [BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki), 'Bech32m' encoding. + +We use the follwoing "Human Readable Parts", or "hrp": + +|hrp|description| +|:-|:-| +|"torrust"|for public keys| +|"torrust_secret"|for secret keys| + +Upon generation the Public and Private keys are displayed to the user.
+_The user should be encouraged to save them in their password manager._ + +``` +Login ID: bech32m("torrust",32-byte-public-key) +Login Code: bech32m("torauth",32-byte-private-key) +``` + +While technically only the private key is needed, we require both as the public key acts as checksum for the private key. This makes it more comfortable for users that are used to traditional password-username based authentication. + +## Authentication +The server and client preform Elliptical Curve Diffie-Hellman over the secp256k1 curve to authenticate: + +_We use the `secp256k1_ecdh` as defined in [secp256k1_ecdh.h](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_ecdh.h), see example: [examples/ecdh.c](https://github.com/bitcoin-core/secp256k1/blob/master/examples/ecdh.c)._ + +### Prerequisites +The server and client generate temporary ephemeral key pairs for every connection attempt. They should not be reused. +``` +Ephemeral Keys: +(E_server, e_server) +(E_client, e_client) + +Client User Key: +(U_client, u_server) +``` + +### Setup +The server transfers their ephemeral public key to the client.
+The client transfers their ephemeral public key and user public key to the server. +``` +Server tx to Client: +(E_server) + +Client tx to Server: +(E_client, U_client) +``` + +### Key Derive +The server and client both derive common secret keys. +``` +Server: +ECDH(E_client, e_server) -> c_ephemeral +ECDH(U_client, e_server) -> c_user + +Client: +ECDH(E_server, e_client) -> c_ephemeral +ECDH(E_server, u_client) -> c_user + +Note: The resulting keys should be identical. +``` + +### Client Auth Token +The client includes their URI to help guard against man-in-the-middle attacks. +``` +Shared RFC 3986 URI: format: "proto://[user@]host[:port][/path]" + +HASH(uri_client || c_ephemeral || c_user) -> token_auth +``` + +### Authentication +The URI should match the expected domain of the server. +``` +Client tx to Server: +(token_auth, uri_client) + +Server Verify: +uri_client +token_auth + +If matching, authorise user according to their user public key. (U_client). +``` + +# Compatibility + +The updated client will support both login in with the new authentication scheme, and transferring existing users with password authentication to the new scheme. + +# Reference Implementations + From 284420eccf0a5d49b6fe530080d9e119faddebc9 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Mon, 29 Aug 2022 17:33:46 +0200 Subject: [PATCH 2/8] TEP 0012: Asymmetric Key Client Authentication --- README.md | 3 ++- TEP-asymmetric_key_client_authentication.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 52521e6..fec6c8a 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,5 @@ If you are wishing to make a new TEP, please consider our TEP Template: [TEP 0]( |Number|Type|Title|Owner|Type|Status| |:-:|:-|:-|:-|:-|:-| [0](/TEP-0000.md)||TEP Template|Constantin Bosse|Process|Active| -[1](/TEP-0001.md)||TEP Purpose and Guidelines|Constantin Bosse|Process|Active| \ No newline at end of file +[1](/TEP-0001.md)||TEP Purpose and Guidelines|Constantin Bosse|Process|Active| +[12](/TEP-0012.md)|Index|Asymmetric Key Client Authentication|Cameron Garnham|Standards Track|Draft| diff --git a/TEP-asymmetric_key_client_authentication.md b/TEP-asymmetric_key_client_authentication.md index 1a5c91a..675fb6e 100644 --- a/TEP-asymmetric_key_client_authentication.md +++ b/TEP-asymmetric_key_client_authentication.md @@ -1,4 +1,4 @@ -|TEP: ????|Asymmetric Key Client Authentication| +|TEP: 00012|Asymmetric Key Client Authentication| |-:|:---| |__Layer:__|Index| |__Authors:__|Cameron Garnham| From 9ec7380712c41c344477821ba5312602d9e1e94d Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Tue, 30 Aug 2022 03:19:15 +0200 Subject: [PATCH 3/8] [tep] rename doc and minor edits. - TEP-asymmetric_key_client_authentication.md -> TEP-0012.md - Some clarifications and expansions based upon Jose's questions. --- ...ey_client_authentication.md => TEP-0012.md | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) rename TEP-asymmetric_key_client_authentication.md => TEP-0012.md (80%) diff --git a/TEP-asymmetric_key_client_authentication.md b/TEP-0012.md similarity index 80% rename from TEP-asymmetric_key_client_authentication.md rename to TEP-0012.md index 675fb6e..6c949d3 100644 --- a/TEP-asymmetric_key_client_authentication.md +++ b/TEP-0012.md @@ -119,7 +119,10 @@ The seed words are prefixed with an additional `"torrust"` word, and displayed t Clients must provide an option for the user to give a seed-password in generation and recovery. -* The client should only need their seed mnemonic code in the case they have lost their other login credentials. +### Storage of Mnemonic Code +The client should delete from memory the recovery seed once the user has confirmed that they have backed up the seed, and the key-pair for login has been generated. + +This gives the user some forward security. In the future the user may wish to use the same seed to rotate their keys (for example, when logging in on a new computer). Because the seed is not saved in the client, if the users' client is compromised at a later date, the seed itself remains secret. ## Public and Private Key Derivation Deriving the keys according to: [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). @@ -130,7 +133,9 @@ m / purpose' / version' / torrust-purpose' / index' m / "torrust" / 0 / "authentication" / 0 ``` -The resulting node is a private-public secp256k1 key-pair. +The resulting node is a private-public secp256k1 key-pair. (the same elliptical-curve as is used in bitcoin). + +___Note:__ as an extension, the future client may choose to register a series of public keys with the server, i.e. 0, 1, 2, 3, etc, and only keep the current key in storage, this will allow for easier key-rotation in the future._ ## Login Credential Encoding For encoding the secp256k1, we use [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) encoding, 32-bytes for public keys.
@@ -215,9 +220,41 @@ token_auth If matching, authorise user according to their user public key. (U_client). ``` +_The server now can issue a session token to the client accordingly._ + +## Security Analysis + +This scheme is very simple, it would be very good there was some formal security analysis. + +The basic protocol follows: + +1. Both derive a common ephemeral (temporary) key:
+`client_ephemeral (DH) server_ephemeral -> ephemeral_key` + +2. Both derive a common authentication key:
+`client_public (DH) server_ephemeral -> authentication_key` + +3. Client derives the common authentication token:
+`sever_uri + ephemeral_key + authentication_key -> authentication_token` + +4. Client sends URI and authentication token to server:
+`client: sever_uri, authentication_token => server` + +5. Server checks `sever_uri` matches expected value. + +6. Server also derives the common authentication token:
+`sever_uri + ephemeral_key + authentication_key -> authentication_token` + `authentication_token` + +7. Server checks the received `authentication_token` matches self-derived value. + # Compatibility The updated client will support both login in with the new authentication scheme, and transferring existing users with password authentication to the new scheme. # Reference Implementations +## Similar Implementations +This scheme is so simple that I guess there should be! + +However, the common ones that I have found are far-more complex than what we use here, (such as getting a CA involved with the authentication). \ No newline at end of file From ff65dbaaafaf180e28373b3736eb4db427c7cc94 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Tue, 30 Aug 2022 18:03:29 +0200 Subject: [PATCH 4/8] [tep] expanded security analysis and storage of derived keys --- TEP-0012.md | 55 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/TEP-0012.md b/TEP-0012.md index 6c949d3..dc31572 100644 --- a/TEP-0012.md +++ b/TEP-0012.md @@ -27,7 +27,7 @@ Currently Torrust uses traditional password-username based authentication: Asymmetric authentication has a number of advantages when compared to password authentication, (assuming the client software is honest): * No need to send any secret data to the server. In contrast, (hashed and salted) passwords that have to be protected from leakage and misuse. -* Synchronization of user-accounts in a group of federated servers becomes much safer: Instead of sharing hashed-passwords between the servers, (or using some centralized authentication service), the servers only need to synchronise the public-keys, without the risk of leaking secert-data. +* Synchronization of user-accounts in a group of federated servers becomes much safer: Instead of sharing hashed-passwords between the servers, (or using some centralized authentication service), the servers only need to synchronise the public-keys, without the risk of leaking secret-data. The disadvantage: * The user no longer picks their own password, instead a private key is generated for the user's client software, this key is 32-bytes long and impossible to remember. If the user looses this code, they loose access to their account. @@ -108,7 +108,8 @@ R: Revoked The server maintains a list of public keys that may be used for authentication for each user. A user may propose a new public key be added to their list of authentication keys, or may revoke or expire an existing key. * To add, or expire, or increase the active period a public key, the user must first authenticate with this new key to prove ownership. -* To revoke, the user doesn't need to authenticate with that key. (However some other form of checks should be preformed, such as verification by a moderator.) +* To revoke, the user may authenticate with the key they wish to revoke.
+Or some other form of authentication should be used in the case that the user no-longer has access to their secret key, such as verification by a moderator. Users who do not have any public key associated, for example new users, or when transitioning from password based authentication should first authenticate with their public key, then preform the association with the user account. @@ -120,7 +121,7 @@ The seed words are prefixed with an additional `"torrust"` word, and displayed t Clients must provide an option for the user to give a seed-password in generation and recovery. ### Storage of Mnemonic Code -The client should delete from memory the recovery seed once the user has confirmed that they have backed up the seed, and the key-pair for login has been generated. +The client should delete from memory the recovery seed once the user has confirmed that they have backed up the seed, and their key-pair(s) have been generated. This gives the user some forward security. In the future the user may wish to use the same seed to rotate their keys (for example, when logging in on a new computer). Because the seed is not saved in the client, if the users' client is compromised at a later date, the seed itself remains secret. @@ -135,7 +136,20 @@ m / "torrust" / 0 / "authentication" / 0 ``` The resulting node is a private-public secp256k1 key-pair. (the same elliptical-curve as is used in bitcoin). -___Note:__ as an extension, the future client may choose to register a series of public keys with the server, i.e. 0, 1, 2, 3, etc, and only keep the current key in storage, this will allow for easier key-rotation in the future._ +___Note:__ as an extension, the future client may choose to derive and register a series of public keys with the server, i.e. indexes: 0, 1, 2, 3, etc, but delete all except the current key from memory.
+This will allow for easier key-rotation in the future, as additional keys cannot be predicted because we use hardened derivation._ + +### Storage of Derived Keys +In general, it is _not recommended_ that a general user would interact with any derived key material, such as the encoded login credentials. It is recommended that clients store this private data in their (long-term) _localStorage_. + +- The client should provide an option to not use any long-term storage, but instead only use their (temporary) _sessionStorage_. +- The client should provide an option to view, backup and manually manage their derived keys. + +There are three main reasons why we wish to provide these possibilities to the user: +1. _Public or Shared Computer Login:_ At internet café's or other places with shared computers. +2. _Multi-User-Account:_ Some users may wish to switch accounts on the same computer. +3. _Password-Manager Support:_ Some users prefer to use a password-manager. + ## Login Credential Encoding For encoding the secp256k1, we use [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) encoding, 32-bytes for public keys.
@@ -148,8 +162,9 @@ We use the follwoing "Human Readable Parts", or "hrp": |"torrust"|for public keys| |"torrust_secret"|for secret keys| -Upon generation the Public and Private keys are displayed to the user.
-_The user should be encouraged to save them in their password manager._ +Upon generation the public and secret keys are stored in the application (either the temporary _sessionStorage_ or the long-term _localStorage_) and may optionally be displayed to the user. + +_If displayed to the user, the user should be encouraged to save them in their password manager._ ``` Login ID: bech32m("torrust",32-byte-public-key) @@ -163,6 +178,8 @@ The server and client preform Elliptical Curve Diffie-Hellman over the secp256k1 _We use the `secp256k1_ecdh` as defined in [secp256k1_ecdh.h](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_ecdh.h), see example: [examples/ecdh.c](https://github.com/bitcoin-core/secp256k1/blob/master/examples/ecdh.c)._ +___Note:__ This scheme assumes that there a secure client connection to the server, for example, by using TLS._ + ### Prerequisites The server and client generate temporary ephemeral key pairs for every connection attempt. They should not be reused. ``` @@ -231,23 +248,41 @@ The basic protocol follows: 1. Both derive a common ephemeral (temporary) key:
`client_ephemeral (DH) server_ephemeral -> ephemeral_key` +_The ephemeral key is used as a nonce to protect against replay attacks._ + 2. Both derive a common authentication key:
`client_public (DH) server_ephemeral -> authentication_key` +_Client knowledge of the authentication key implicitly shows ownership of the client public key._ + 3. Client derives the common authentication token:
-`sever_uri + ephemeral_key + authentication_key -> authentication_token` +`server_uri + ephemeral_key + authentication_key -> authentication_token` + +_Mixing in the server's uri helps protect the user from a bad-server impersonating another server._ 4. Client sends URI and authentication token to server:
-`client: sever_uri, authentication_token => server` +`client: server_uri, authentication_token => server` + +_The server does not learn of the ephemeral key and authentication key from the user. The server only learns the server uri and authentication token from the client._ + +_If the server was impersonating another server, the uri would not match._ + +5. Server checks `server_uri` matches expected value. -5. Server checks `sever_uri` matches expected value. +_This protects the client from the wrong server attack: if the user connects to `a.tld`, the uri will not match for `b.tdl`._ + +_Man in the middle attackers are unable to use an alternative uri._ 6. Server also derives the common authentication token:
-`sever_uri + ephemeral_key + authentication_key -> authentication_token` +`server_uri + ephemeral_key + authentication_key -> authentication_token` `authentication_token` +_This token includes the uri, nonce, and client public key._ + 7. Server checks the received `authentication_token` matches self-derived value. +_If the keys match, the client is authenticated for their client public key._ + # Compatibility The updated client will support both login in with the new authentication scheme, and transferring existing users with password authentication to the new scheme. From 0d505fbe89e8d441a9cf5f68c9e2b2b5cf1562dd Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Thu, 8 Sep 2022 15:36:20 +0200 Subject: [PATCH 5/8] protocol: update scheme to stop passive key leakage --- TEP-0012.md | 132 ++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 88 deletions(-) diff --git a/TEP-0012.md b/TEP-0012.md index dc31572..60b8d58 100644 --- a/TEP-0012.md +++ b/TEP-0012.md @@ -1,4 +1,4 @@ -|TEP: 00012|Asymmetric Key Client Authentication| +|TEP: 00012|One-Sided Passkey Authentication| |-:|:---| |__Layer:__|Index| |__Authors:__|Cameron Garnham| @@ -15,7 +15,7 @@ This document proposes the use of asymmetric cryptography for user accounts and their authentication. ## Copyright -This document is licensed under the 2-clause BSD license. +This document is licensed under the 2-clause BSD licence. ## Motivation Currently Torrust uses traditional password-username based authentication: @@ -155,7 +155,7 @@ There are three main reasons why we wish to provide these possibilities to the u For encoding the secp256k1, we use [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) encoding, 32-bytes for public keys.
For displaying the login credentials, we use [BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki), 'Bech32m' encoding. -We use the follwoing "Human Readable Parts", or "hrp": +We use the following "Human Readable Parts", or "hrp": |hrp|description| |:-|:-| @@ -178,110 +178,66 @@ The server and client preform Elliptical Curve Diffie-Hellman over the secp256k1 _We use the `secp256k1_ecdh` as defined in [secp256k1_ecdh.h](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_ecdh.h), see example: [examples/ecdh.c](https://github.com/bitcoin-core/secp256k1/blob/master/examples/ecdh.c)._ -___Note:__ This scheme assumes that there a secure client connection to the server, for example, by using TLS._ +___Note:__ This scheme assumes that the client has authenticated the servers' domain using TLS._ -### Prerequisites -The server and client generate temporary ephemeral key pairs for every connection attempt. They should not be reused. -``` -Ephemeral Keys: -(E_server, e_server) -(E_client, e_client) +- _This scheme is not secure against domain spoofing attacks._ -Client User Key: -(U_client, u_server) -``` +### Protocol: -### Setup -The server transfers their ephemeral public key to the client.
-The client transfers their ephemeral public key and user public key to the server. -``` -Server tx to Client: -(E_server) +1. Client receives the Server Ephemeral Public Key:
+`E_server` -Client tx to Server: -(E_client, U_client) -``` +2. Client derives the Ephemeral Common Key using ECDH:
+`E_server (dh) e_client = e_common` -### Key Derive -The server and client both derive common secret keys. -``` -Server: -ECDH(E_client, e_server) -> c_ephemeral -ECDH(U_client, e_server) -> c_user +3. Client tweaks their User Authentication Keypair with the Ephemeral Common Key:
+`A_user + e_common = A'_user`
+`a_user + e_common = a'_user` -Client: -ECDH(E_server, e_client) -> c_ephemeral -ECDH(E_server, u_client) -> c_user +4. Client derives the Tweaked Common Authentication Key using ECDH:
+`E_server (dh) a'_user = a'_common` -Note: The resulting keys should be identical. -``` +5. Client mixes the Servers URI into the Tweaked Authentication Code:
+`a'_common (hash) URI_server = A'_auth` -### Client Auth Token -The client includes their URI to help guard against man-in-the-middle attacks. -``` -Shared RFC 3986 URI: format: "proto://[user@]host[:port][/path]" +6. Server receives the Client Ephemeral Public Key, Tweaked User Authentication Public Key, Tweaked Authentication Code, and the URI:
+`E_client`
+`A'_user`
+`A'_auth`
+`URI_server` +7. Server derives the Common Ephemeral Key using ECDH:
+`E_client (dh) e_server = e_common` -HASH(uri_client || c_ephemeral || c_user) -> token_auth -``` +8. Server derives the Tweaked Common Authentication Key using ECDH:
+`A'_client (dh) e_server = a'_common` -### Authentication -The URI should match the expected domain of the server. -``` -Client tx to Server: -(token_auth, uri_client) +9. Server untweaks the Tweaked User Authentication Public Key: +`A'_user - e_common = A_user` -Server Verify: -uri_client -token_auth +10. Server checks the Tweaked Authentication Code:
+`A'_auth == a'_common (hash) URI_server` -If matching, authorise user according to their user public key. (U_client). -``` +11. Server checks the URI:
+`URI_server == URI_server` +12. Server finds the User Authentication Public Key in its database and confirms the authentication:
+`if "A_user" is good, authentcate for the client: "E_client"` -_The server now can issue a session token to the client accordingly._ +_The server now can issue a session token to the client._ ## Security Analysis -This scheme is very simple, it would be very good there was some formal security analysis. - -The basic protocol follows: - -1. Both derive a common ephemeral (temporary) key:
-`client_ephemeral (DH) server_ephemeral -> ephemeral_key` - -_The ephemeral key is used as a nonce to protect against replay attacks._ - -2. Both derive a common authentication key:
-`client_public (DH) server_ephemeral -> authentication_key` - -_Client knowledge of the authentication key implicitly shows ownership of the client public key._ - -3. Client derives the common authentication token:
-`server_uri + ephemeral_key + authentication_key -> authentication_token` - -_Mixing in the server's uri helps protect the user from a bad-server impersonating another server._ - -4. Client sends URI and authentication token to server:
-`client: server_uri, authentication_token => server` - -_The server does not learn of the ephemeral key and authentication key from the user. The server only learns the server uri and authentication token from the client._ - -_If the server was impersonating another server, the uri would not match._ - -5. Server checks `server_uri` matches expected value. - -_This protects the client from the wrong server attack: if the user connects to `a.tld`, the uri will not match for `b.tdl`._ - -_Man in the middle attackers are unable to use an alternative uri._ - -6. Server also derives the common authentication token:
-`server_uri + ephemeral_key + authentication_key -> authentication_token` - `authentication_token` +This scheme is strong against the passive observer, observable information: +- Existence of the scheme. (Eve can observe that this scheme is happening.) +- The URI of server according to the client. (This could be easily encrypted as an enhancement.) -_This token includes the uri, nonce, and client public key._ +This scheme is strong against the passive proxy attack: +- If user has the wrong URI according to the server, the authentication will not be successful. -7. Server checks the received `authentication_token` matches self-derived value. +This scheme is strong against man-in-the-middle attacks, except for: +- Leaked User Authentication Public Key. (Malory can trick Alice into revealing her User Authentication Public Key.) +- False Authentication. (Malory can fool Alice into thinking that she has been successfully authenticated.) -_If the keys match, the client is authenticated for their client public key._ +Malory is unable to succeed with the man-in-the-middle attack, while he is able to impersonate Bob, he is unable to impersonate Alice, because Bob has a record of Alice's Public Key. # Compatibility From 63c8f1b8a6054264648da6290864e44542b55fd0 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Wed, 5 Oct 2022 20:20:04 +0200 Subject: [PATCH 6/8] [fix] Corrections from review. * Spelling Mistakes and Mislabelling. * Merge Step 9 into step 12 in authentication scheme. Co-authored-by: cilli0n --- TEP-0012.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/TEP-0012.md b/TEP-0012.md index 60b8d58..1b308de 100644 --- a/TEP-0012.md +++ b/TEP-0012.md @@ -78,7 +78,7 @@ Likewise, Each _purposed public key_ may look up what _users_ it is associated w - Each _(user <> purposed public key)_ link can look up it's associated _timed statuses_. ### Purposes -In this document we only user the `A` for "Authentication".
In the future we may propose additional purposes. +In this document we only use the `A` for "Authentication".
In the future we may propose additional purposes. ``` Purposes (enum): @@ -168,7 +168,7 @@ _If displayed to the user, the user should be encouraged to save them in their p ``` Login ID: bech32m("torrust",32-byte-public-key) -Login Code: bech32m("torauth",32-byte-private-key) +Login Code: bech32m("torrust_secret",32-byte-private-key) ``` While technically only the private key is needed, we require both as the public key acts as checksum for the private key. This makes it more comfortable for users that are used to traditional password-username based authentication. @@ -205,22 +205,22 @@ ___Note:__ This scheme assumes that the client has authenticated the servers' do `A'_user`
`A'_auth`
`URI_server` + 7. Server derives the Common Ephemeral Key using ECDH:
`E_client (dh) e_server = e_common` 8. Server derives the Tweaked Common Authentication Key using ECDH:
-`A'_client (dh) e_server = a'_common` - -9. Server untweaks the Tweaked User Authentication Public Key: -`A'_user - e_common = A_user` +`A'_user (dh) e_server = a'_common` -10. Server checks the Tweaked Authentication Code:
+9. Server checks the Tweaked Authentication Code:
`A'_auth == a'_common (hash) URI_server` -11. Server checks the URI:
+10. Server checks the URI:
`URI_server == URI_server` -12. Server finds the User Authentication Public Key in its database and confirms the authentication:
-`if "A_user" is good, authentcate for the client: "E_client"` + +11. Server untweaks the Tweaked User Authentication Public Key and finds the User Authentication Public Key in its database to confirm the authentication:
+`A'_user - e_common = A_user`
+`if "A_user" is good, authenticate for the client: "E_client"` _The server now can issue a session token to the client._ From 0c9816163908481b5578aafb04a72d03340d5cea Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Wed, 5 Oct 2022 20:48:10 +0200 Subject: [PATCH 7/8] [fix] update TEP-12 name in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fec6c8a..42c9a38 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ If you are wishing to make a new TEP, please consider our TEP Template: [TEP 0]( |:-:|:-|:-|:-|:-|:-| [0](/TEP-0000.md)||TEP Template|Constantin Bosse|Process|Active| [1](/TEP-0001.md)||TEP Purpose and Guidelines|Constantin Bosse|Process|Active| -[12](/TEP-0012.md)|Index|Asymmetric Key Client Authentication|Cameron Garnham|Standards Track|Draft| +[12](/TEP-0012.md)|Index|One-Sided Passkey Authentication|Cameron Garnham|Standards Track|Draft| From 90fb11d43fa9d89276ffb35c3e6e177ea6c6aaff Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Thu, 24 Nov 2022 19:29:14 +0100 Subject: [PATCH 8/8] fixup: correct markdown lint --- TEP-0012.md | 70 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/TEP-0012.md b/TEP-0012.md index 1b308de..be081c1 100644 --- a/TEP-0012.md +++ b/TEP-0012.md @@ -12,12 +12,15 @@ # Introduction ## Abstract + This document proposes the use of asymmetric cryptography for user accounts and their authentication. ## Copyright -This document is licensed under the 2-clause BSD licence. + +This document is licensed under the 2-clause BSD licence. ## Motivation + Currently Torrust uses traditional password-username based authentication: * For every user the server stores a username, salt, and hashed password. @@ -26,33 +29,40 @@ Currently Torrust uses traditional password-username based authentication: * If matching, the client is authenticated as that user. Asymmetric authentication has a number of advantages when compared to password authentication, (assuming the client software is honest): + * No need to send any secret data to the server. In contrast, (hashed and salted) passwords that have to be protected from leakage and misuse. * Synchronization of user-accounts in a group of federated servers becomes much safer: Instead of sharing hashed-passwords between the servers, (or using some centralized authentication service), the servers only need to synchronise the public-keys, without the risk of leaking secret-data. The disadvantage: + * The user no longer picks their own password, instead a private key is generated for the user's client software, this key is 32-bytes long and impossible to remember. If the user looses this code, they loose access to their account. This disadvantage is mitigated by providing the user with a 'backup seed' when they generate their private key, that the user can use to recover their private key. # Design + We first describe the database and user-structure, and general protocols, then we specify clients generating new private keys, and finally describe the public key authentication protocol. ## Overview + New Users: + 1. Client generates secret keys, and derives public key. 2. Client and server preform the Diffie-Hellman authentication protocol. 3. Client creates username, and the public key is associated the username. Existing Users: + 1. Client and server preform the Diffie-Hellman authentication protocol. 2. Client selects username that it wishes to login with. (There may be more than one username that is associated with the same public key). ## Users + A username is the unique key in the database retaining to the actions of a user. Public keys are associated with users, for a particular purpose. Every public-key-purpose combination has a set of timed status. -``` +```Text [user] (PK. String) username @@ -73,22 +83,27 @@ A username is the unique key in the database retaining to the actions of a user. ``` _"Users and Purposed-Public-Keys have a many-many association, each association may associate many timed statuses.":_ -- Each _user_ may look up what _purposed public keys_ it is associated with.
+ +* Each _user_ may look up what _purposed public keys_ it is associated with.
Likewise, Each _purposed public key_ may look up what _users_ it is associated with. -- Each _(user <> purposed public key)_ link can look up it's associated _timed statuses_. +* Each _(user <> purposed public key)_ link can look up it's associated _timed statuses_. ### Purposes + In this document we only use the `A` for "Authentication".
In the future we may propose additional purposes. -``` + +```Text Purposes (enum): A: Authentication ``` ### Status Validity + If revocation does not specify a beginning, it is for all time periods.
`Active` has the lowest priority: The key must be `created`, and not `expired`, and not `revoked`. -``` + +```Text Status (enum): A: Active @@ -96,7 +111,9 @@ C: Created E: Expired R: Revoked ``` -#### Status Validity Table: + +#### Status Validity Table + |status|beginning|end| |:-|:-|:-| |active|must|must| @@ -105,6 +122,7 @@ R: Revoked |revoked|optional|none| # Specification + The server maintains a list of public keys that may be used for authentication for each user. A user may propose a new public key be added to their list of authentication keys, or may revoke or expire an existing key. * To add, or expire, or increase the active period a public key, the user must first authenticate with this new key to prove ownership. @@ -114,6 +132,7 @@ Or some other form of authentication should be used in the case that the user no Users who do not have any public key associated, for example new users, or when transitioning from password based authentication should first authenticate with their public key, then preform the association with the user account. ## Mnemonic Codes + Clients generate a mnemonic code according to: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). The seed words are prefixed with an additional `"torrust"` word, and displayed to the user. The 'torrust' seed word is not included in the checksum calculation, however must be present when the user enters their seed in recovery. @@ -121,37 +140,43 @@ The seed words are prefixed with an additional `"torrust"` word, and displayed t Clients must provide an option for the user to give a seed-password in generation and recovery. ### Storage of Mnemonic Code + The client should delete from memory the recovery seed once the user has confirmed that they have backed up the seed, and their key-pair(s) have been generated. This gives the user some forward security. In the future the user may wish to use the same seed to rotate their keys (for example, when logging in on a new computer). Because the seed is not saved in the client, if the users' client is compromised at a later date, the seed itself remains secret. ## Public and Private Key Derivation + Deriving the keys according to: [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). We use the following hardened derivation path:
The index is increased in the case the user has rotated their keys, for the moment we only use zero: -``` + +```Text m / purpose' / version' / torrust-purpose' / index' m / "torrust" / 0 / "authentication" / 0 ``` + The resulting node is a private-public secp256k1 key-pair. (the same elliptical-curve as is used in bitcoin). ___Note:__ as an extension, the future client may choose to derive and register a series of public keys with the server, i.e. indexes: 0, 1, 2, 3, etc, but delete all except the current key from memory.
This will allow for easier key-rotation in the future, as additional keys cannot be predicted because we use hardened derivation._ ### Storage of Derived Keys + In general, it is _not recommended_ that a general user would interact with any derived key material, such as the encoded login credentials. It is recommended that clients store this private data in their (long-term) _localStorage_. -- The client should provide an option to not use any long-term storage, but instead only use their (temporary) _sessionStorage_. -- The client should provide an option to view, backup and manually manage their derived keys. +* The client should provide an option to not use any long-term storage, but instead only use their (temporary) _sessionStorage_. +* The client should provide an option to view, backup and manually manage their derived keys. There are three main reasons why we wish to provide these possibilities to the user: + 1. _Public or Shared Computer Login:_ At internet café's or other places with shared computers. 2. _Multi-User-Account:_ Some users may wish to switch accounts on the same computer. 3. _Password-Manager Support:_ Some users prefer to use a password-manager. - ## Login Credential Encoding + For encoding the secp256k1, we use [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) encoding, 32-bytes for public keys.
For displaying the login credentials, we use [BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki), 'Bech32m' encoding. @@ -166,7 +191,7 @@ Upon generation the public and secret keys are stored in the application (either _If displayed to the user, the user should be encouraged to save them in their password manager._ -``` +```Text Login ID: bech32m("torrust",32-byte-public-key) Login Code: bech32m("torrust_secret",32-byte-private-key) ``` @@ -174,15 +199,16 @@ Login Code: bech32m("torrust_secret",32-byte-private-key) While technically only the private key is needed, we require both as the public key acts as checksum for the private key. This makes it more comfortable for users that are used to traditional password-username based authentication. ## Authentication + The server and client preform Elliptical Curve Diffie-Hellman over the secp256k1 curve to authenticate: _We use the `secp256k1_ecdh` as defined in [secp256k1_ecdh.h](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_ecdh.h), see example: [examples/ecdh.c](https://github.com/bitcoin-core/secp256k1/blob/master/examples/ecdh.c)._ ___Note:__ This scheme assumes that the client has authenticated the servers' domain using TLS._ -- _This scheme is not secure against domain spoofing attacks._ +* _This scheme is not secure against domain spoofing attacks._ -### Protocol: +### Protocol 1. Client receives the Server Ephemeral Public Key:
`E_server` @@ -227,15 +253,18 @@ _The server now can issue a session token to the client._ ## Security Analysis This scheme is strong against the passive observer, observable information: -- Existence of the scheme. (Eve can observe that this scheme is happening.) -- The URI of server according to the client. (This could be easily encrypted as an enhancement.) + +* Existence of the scheme. (Eve can observe that this scheme is happening.) +* The URI of server according to the client. (This could be easily encrypted as an enhancement.) This scheme is strong against the passive proxy attack: -- If user has the wrong URI according to the server, the authentication will not be successful. + +* If user has the wrong URI according to the server, the authentication will not be successful. This scheme is strong against man-in-the-middle attacks, except for: -- Leaked User Authentication Public Key. (Malory can trick Alice into revealing her User Authentication Public Key.) -- False Authentication. (Malory can fool Alice into thinking that she has been successfully authenticated.) + +* Leaked User Authentication Public Key. (Malory can trick Alice into revealing her User Authentication Public Key.) +* False Authentication. (Malory can fool Alice into thinking that she has been successfully authenticated.) Malory is unable to succeed with the man-in-the-middle attack, while he is able to impersonate Bob, he is unable to impersonate Alice, because Bob has a record of Alice's Public Key. @@ -246,6 +275,7 @@ The updated client will support both login in with the new authentication scheme # Reference Implementations ## Similar Implementations + This scheme is so simple that I guess there should be! -However, the common ones that I have found are far-more complex than what we use here, (such as getting a CA involved with the authentication). \ No newline at end of file +However, the common ones that I have found are far-more complex than what we use here, (such as getting a CA involved with the authentication).