Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages: * managing public keys can be easier than managing shared secrets. * The encoding is slightly shorter, since no IV is needed, since K2 is different every time. * probably others?
Disadvantages: * Curve25519 costs more computationally than non-public-key operations * probably others?
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hey Nick,
thanks for the feedback on the torspec patch and this scheme. I'll wait to figure out if we want to use this scheme before updating the torspec patch further.
This proposed scheme seems like a good idea. It basically switches the identity of authed clients from symmetric keys to x25519 keys, which seems more intuitive and correct.
I wonder if clients could/should use the same keypair for intro-layer authentication as well. Section 3.4.2 currently specifies how to do intro-layer auth using ed25519 keys, so perhaps we can use a single curve25519 key (and switch it between ed25519 and x25519) to perform both descriptor-layer and intro-layer authentication?
WRT the suggested scheme, I think my biggest concern here is the UX, and specifically this phrase
"Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key".
The client auth UX currently involves the HS operator passing credentials to the clients, not the other way around. This is good for UX since it means that all configuration is performed by the HS operator (who can be assumed technical), instead of its clients (who should be assumed to be non-technical). All clients need to do is copy-paste the auth line to their torrc. I feel like this UX should be maintained, except if there is a very strong reason to break it.
I think your proposal could be slightly tweaked to fit the above UX, if the HS generates the client's private keys, and then passes them to the clients. The rest works the same. Perhaps we can also give the option for clients to generate the keys themselves if they so want.
Having the HS generate its client's private keys, kind of beats the purpose of having assymetric crypto keys, since we basically treat them as shared secrets. However, I don't think this changes the threat model in any significant way, as the hidden service can be seen a trusted party in some sense. Some more thinking needs to be done here.
The way I see it, by using this proposed scheme, we get a nicer cryptographic scheme (symmetric keys kind of suck) and a more compact auth-client format, for the price of a bit more engineering (generating ephemeral keypairs and encoding them in descriptors). I think this might be worth it.
George Kadianakis desnacked@riseup.net writes:
[ text/plain ] Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hey Nick,
thanks for the feedback on the torspec patch and this scheme. I'll wait to figure out if we want to use this scheme before updating the torspec patch further.
This proposed scheme seems like a good idea. It basically switches the identity of authed clients from symmetric keys to x25519 keys, which seems more intuitive and correct.
I wonder if clients could/should use the same keypair for intro-layer authentication as well. Section 3.4.2 currently specifies how to do intro-layer auth using ed25519 keys, so perhaps we can use a single curve25519 key (and switch it between ed25519 and x25519) to perform both descriptor-layer and intro-layer authentication?
WRT the suggested scheme, I think my biggest concern here is the UX, and specifically this phrase
"Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key".
The client auth UX currently involves the HS operator passing credentials to the clients, not the other way around. This is good for UX since it means that all configuration is performed by the HS operator (who can be assumed technical), instead of its clients (who should be assumed to be non-technical). All clients need to do is copy-paste the auth line to their torrc. I feel like this UX should be maintained, except if there is a very strong reason to break it.
OK, I think sooner or later we needed to have a UX discussion about HS client authorization!
The current rend-spec.txt specifies the torrc options for client auth in sections 2.3/2.4. We don't do this in prop224 yet, but I think it's useful because figuring out the torrc format now will help us understand if the scheme we are making is useful.
Here is a rough proposed UX for prop224 client auth, using Nick's idea from the top post of this thread. FWIW, I've used the same torrc option naming as we currently have but we should probably introduce new ones.
-- Hidden Service configuration
A hidden service uses the following torrc line to specify authed clients:
HiddenServiceAuthorizeClient <auth-type> <client-name>,<client-name>,...
If this option is configured, Tor generates client authorization data and creates a new "hs_client_auth.txt" file which contains lines with the following format:
client-name <client-name> NL HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64> NL
where <client-name> is a nickname for the authed client, <desc-x25519-key-privb64> is an x25519 private key used to generate descriptor encryption keys (as Nick specified in top mail), and <desc-ed25519-privkey-b64> is an ed25519 private key used to perform the INTRO1 authorization protocol (as specified in section 3.4.2 of prop224).
e.g. client-name alice HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion 2vMVLDEAu+rc0rXFONpnor9mfG5xj0ovSh+YWIvOAvQ= qtXjslfyvPokRGFkzGnTXK7ICUNnoFyQRMORN/Zn4ss= client-name bob HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU= client-name charlie HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU=
The idea here is that HS operators find the right HidServAuth line and paste it to their clients out-of-band, who then copy pastes it into their torrc file (or ideally plug it through tor browser in the future).
We should also make it possible for clients to provide their own private keys. We should introduce a keygen command for clients which generates a "HidServAuth" line, and then they can pass it to the HS operator, who puts it in their hs_client_auth.txt. Unclear what's the best UX way to do this; probably it should be a tor browser utility or sth...
-- Client configuration
For client configuration, we use the HidServAuth format intact from above. So basically, clients can add HS client auth information by placing the following lines in their torrc:
HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64>
where format is as explained above.
-- Discussion
Here are some topics for discussion:
- Can we improve the service-side file format for hs_client_auth.txt? It kind of sucks big time...
Perhaps a new file should be made for each authed client and put in a special client-auth/ dir? Or perhaps we have already lost the UX game here, and we should instead provide a utility for services and clients that handles the authorization credential encoding and configuration?
- What's up with the username/password intro-level auth specified in prop224 section 3.4.1? I guess the whole point for having username/password auth is so that they are memorable. However, if we always require a descriptor-level x25519 auth key anyhow, we don't get much by making the intro-level credentials human memorable.
Should we just ditch the username/password method completely for now? Or alternatively (and more crazy) we should generate x25519 private keys using the low-entropy human-memorable username/password combo.
- What changes do we need in tor browser to make hidden service authorization more useful? We should probably involve the UX team here.
- Should we use a single curve25519 public key for client-auth and transform it between ed25519 and curve25519 instead of having two separate keys? I decided to go with the conservative approach, as the UX benefits are not that great.
On 11 Nov. 2016, at 04:18, George Kadianakis desnacked@riseup.net wrote:
George Kadianakis desnacked@riseup.net writes:
[ text/plain ] Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hey Nick,
thanks for the feedback on the torspec patch and this scheme. I'll wait to figure out if we want to use this scheme before updating the torspec patch further.
This proposed scheme seems like a good idea. It basically switches the identity of authed clients from symmetric keys to x25519 keys, which seems more intuitive and correct.
I wonder if clients could/should use the same keypair for intro-layer authentication as well. Section 3.4.2 currently specifies how to do intro-layer auth using ed25519 keys, so perhaps we can use a single curve25519 key (and switch it between ed25519 and x25519) to perform both descriptor-layer and intro-layer authentication?
WRT the suggested scheme, I think my biggest concern here is the UX, and specifically this phrase
"Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key".
The client auth UX currently involves the HS operator passing credentials to the clients, not the other way around. This is good for UX since it means that all configuration is performed by the HS operator (who can be assumed technical), instead of its clients (who should be assumed to be non-technical). All clients need to do is copy-paste the auth line to their torrc. I feel like this UX should be maintained, except if there is a very strong reason to break it.
OK, I think sooner or later we needed to have a UX discussion about HS client authorization!
The current rend-spec.txt specifies the torrc options for client auth in sections 2.3/2.4. We don't do this in prop224 yet, but I think it's useful because figuring out the torrc format now will help us understand if the scheme we are making is useful.
Here is a rough proposed UX for prop224 client auth, using Nick's idea from the top post of this thread. FWIW, I've used the same torrc option naming as we currently have but we should probably introduce new ones.
-- Hidden Service configuration
A hidden service uses the following torrc line to specify authed clients:
HiddenServiceAuthorizeClient <auth-type> <client-name>,<client-name>,...
If this option is configured, Tor generates client authorization data and creates a new "hs_client_auth.txt" file which contains lines with the following format:
client-name <client-name> NL HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64> NL
where <client-name> is a nickname for the authed client, <desc-x25519-key-privb64> is an x25519 private key used to generate descriptor encryption keys (as Nick specified in top mail), and <desc-ed25519-privkey-b64> is an ed25519 private key used to perform the INTRO1 authorization protocol (as specified in section 3.4.2 of prop224).
e.g. client-name alice HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion 2vMVLDEAu+rc0rXFONpnor9mfG5xj0ovSh+YWIvOAvQ= qtXjslfyvPokRGFkzGnTXK7ICUNnoFyQRMORN/Zn4ss= client-name bob HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU= client-name charlie HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU=
The idea here is that HS operators find the right HidServAuth line and paste it to their clients out-of-band, who then copy pastes it into their torrc file (or ideally plug it through tor browser in the future).
I think we should discourage people handing around shared private keys.
In particular, it's poor UI for the hidden service to generate private keys that only the user should know.
And it's even worse UI for the hidden service to take private keys as input - it should only ever take the public keys as input, even if we decide that it should generate the private keys for clients, it should not need to keep them around.
We should also make it possible for clients to provide their own private keys. We should introduce a keygen command for clients which generates a "HidServAuth" line, and then they can pass it to the HS operator, who puts it in their hs_client_auth.txt. Unclear what's the best UX way to do this; probably it should be a tor browser utility or sth…
I really do think this should be the default. Otherwise, the HS operator knows the private keys. (Although I don't think this breaks much, conceptually, it looks bad.)
-- Client configuration
For client configuration, we use the HidServAuth format intact from above. So basically, clients can add HS client auth information by placing the following lines in their torrc:
HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64>
where format is as explained above.
Maybe we could also allow a directory with one file per hidden service? That way, if each private key is generated in a separate file by the HS (see below), these files can be dropped in that directory, without subjecting users to copy-paste errors (only newline changes!)
-- Discussion
Here are some topics for discussion:
- Can we improve the service-side file format for hs_client_auth.txt?
It kind of sucks big time...
Perhaps a new file should be made for each authed client and put in a special client-auth/ dir? Or perhaps we have already lost the UX game here, and we should instead provide a utility for services and clients that handles the authorization credential encoding and configuration?
One file per client private key seems sensible, then the file can be sent to each client, and deleted after sending.
A single file for all the client public keys seems reasonable, they're not sensitive.
- What's up with the username/password intro-level auth specified in
prop224 section 3.4.1? I guess the whole point for having username/password auth is so that they are memorable. However, if we always require a descriptor-level x25519 auth key anyhow, we don't get much by making the intro-level credentials human memorable.
Should we just ditch the username/password method completely for now? Or alternatively (and more crazy) we should generate x25519 private keys using the low-entropy human-memorable username/password combo.
This seems sensible - can we simplify every authentication method down to a key expansion function that yields x25519 keys?
- What changes do we need in tor browser to make hidden service
authorization more useful? We should probably involve the UX team here.
Do we want to use the user:pass@domain format? (If we use this format, does Tor's SOCKS proxy even see the user:pass?) If so, we might regret using base64 for these keys.
- Should we use a single curve25519 public key for client-auth and
transform it between ed25519 and curve25519 instead of having two separate keys? I decided to go with the conservative approach, as the UX benefits are not that great.
If I ever had to type one of those out manually, I'd want a single key.
T
teor teor2345@gmail.com writes:
[ text/plain ]
On 11 Nov. 2016, at 04:18, George Kadianakis desnacked@riseup.net wrote:
George Kadianakis desnacked@riseup.net writes:
[ text/plain ] Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hey Nick,
thanks for the feedback on the torspec patch and this scheme. I'll wait to figure out if we want to use this scheme before updating the torspec patch further.
This proposed scheme seems like a good idea. It basically switches the identity of authed clients from symmetric keys to x25519 keys, which seems more intuitive and correct.
I wonder if clients could/should use the same keypair for intro-layer authentication as well. Section 3.4.2 currently specifies how to do intro-layer auth using ed25519 keys, so perhaps we can use a single curve25519 key (and switch it between ed25519 and x25519) to perform both descriptor-layer and intro-layer authentication?
WRT the suggested scheme, I think my biggest concern here is the UX, and specifically this phrase
"Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key".
The client auth UX currently involves the HS operator passing credentials to the clients, not the other way around. This is good for UX since it means that all configuration is performed by the HS operator (who can be assumed technical), instead of its clients (who should be assumed to be non-technical). All clients need to do is copy-paste the auth line to their torrc. I feel like this UX should be maintained, except if there is a very strong reason to break it.
OK, I think sooner or later we needed to have a UX discussion about HS client authorization!
The current rend-spec.txt specifies the torrc options for client auth in sections 2.3/2.4. We don't do this in prop224 yet, but I think it's useful because figuring out the torrc format now will help us understand if the scheme we are making is useful.
Here is a rough proposed UX for prop224 client auth, using Nick's idea from the top post of this thread. FWIW, I've used the same torrc option naming as we currently have but we should probably introduce new ones.
-- Hidden Service configuration
A hidden service uses the following torrc line to specify authed clients:
HiddenServiceAuthorizeClient <auth-type> <client-name>,<client-name>,...
If this option is configured, Tor generates client authorization data and creates a new "hs_client_auth.txt" file which contains lines with the following format:
client-name <client-name> NL HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64> NL
where <client-name> is a nickname for the authed client, <desc-x25519-key-privb64> is an x25519 private key used to generate descriptor encryption keys (as Nick specified in top mail), and <desc-ed25519-privkey-b64> is an ed25519 private key used to perform the INTRO1 authorization protocol (as specified in section 3.4.2 of prop224).
e.g. client-name alice HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion 2vMVLDEAu+rc0rXFONpnor9mfG5xj0ovSh+YWIvOAvQ= qtXjslfyvPokRGFkzGnTXK7ICUNnoFyQRMORN/Zn4ss= client-name bob HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU= client-name charlie HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU=
The idea here is that HS operators find the right HidServAuth line and paste it to their clients out-of-band, who then copy pastes it into their torrc file (or ideally plug it through tor browser in the future).
I think we should discourage people handing around shared private keys.
In particular, it's poor UI for the hidden service to generate private keys that only the user should know.
And it's even worse UI for the hidden service to take private keys as input - it should only ever take the public keys as input, even if we decide that it should generate the private keys for clients, it should not need to keep them around.
We should also make it possible for clients to provide their own private keys. We should introduce a keygen command for clients which generates a "HidServAuth" line, and then they can pass it to the HS operator, who puts it in their hs_client_auth.txt. Unclear what's the best UX way to do this; probably it should be a tor browser utility or sth…
I really do think this should be the default. Otherwise, the HS operator knows the private keys. (Although I don't think this breaks much, conceptually, it looks bad.)
I definitely agree it conceptually looks bad and/or dump for the hidden service to generate private keys and pass them to its users, even though it probably does not really affect security that much. Let's try to think of alternatives:
a) Clients securely generate keypairs and pass their pubkeys to the HS.
This is basically the SSH authorized_keys model, and it looks like the conceptually right way of doing this, but this definitely changes the UX in a major way.
I think the most painful thing here is that we will need to introduce a client-side keygen utility that will generate these keypairs, and present them to the user. It's unclear how we would do that, and it's extra engineering and UX analysis, since we need to assume that HS clients are not tech savvy and do not understand what public/private keys are.
Also, it means that clients need to _securely_ send credentials to the HS operator and then they need to _wait_ till the HS operator adds those creds to Tor, before they are able to visit the HS. Till the HS operator adds their creds to Tor, authed client connections to the HS will fail silently since there is no NACK from the service and they will just be unable to complete rendezvous. We should probably speak with people that use client auth to tell us if this UX will break their model.
b) We can change the client auth methods to use symmetric keys, instead of assymetric keys. This way we avoid passing private keys to users.
This might be a plausible way forward and potentially worth exploring.
For descriptor-level authorization, using symmetric keys is straightforward since we just need to do the same thing that we are now doing in rend-spec.txt (it's basically the scheme I posted in https://lists.torproject.org/pipermail/tor-dev/2016-November/011617.html)
For intro-level authorization, prop224 suggests we use ed25519 signatures for clients to prove ownership of their private key. We could perhaps switch those signatures to be MAC tags, so that we can perform those with symmetric keys.
What else can we do here? And am I perhaps overthinking of the UX issue here?
Cheers!
On 12 Nov. 2016, at 03:41, George Kadianakis desnacked@riseup.net wrote:
teor teor2345@gmail.com writes:
[ text/plain ]
On 11 Nov. 2016, at 04:18, George Kadianakis desnacked@riseup.net wrote:
George Kadianakis desnacked@riseup.net writes:
[ text/plain ] Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hey Nick,
thanks for the feedback on the torspec patch and this scheme. I'll wait to figure out if we want to use this scheme before updating the torspec patch further.
This proposed scheme seems like a good idea. It basically switches the identity of authed clients from symmetric keys to x25519 keys, which seems more intuitive and correct.
I wonder if clients could/should use the same keypair for intro-layer authentication as well. Section 3.4.2 currently specifies how to do intro-layer auth using ed25519 keys, so perhaps we can use a single curve25519 key (and switch it between ed25519 and x25519) to perform both descriptor-layer and intro-layer authentication?
WRT the suggested scheme, I think my biggest concern here is the UX, and specifically this phrase
"Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key".
The client auth UX currently involves the HS operator passing credentials to the clients, not the other way around. This is good for UX since it means that all configuration is performed by the HS operator (who can be assumed technical), instead of its clients (who should be assumed to be non-technical). All clients need to do is copy-paste the auth line to their torrc. I feel like this UX should be maintained, except if there is a very strong reason to break it.
OK, I think sooner or later we needed to have a UX discussion about HS client authorization!
The current rend-spec.txt specifies the torrc options for client auth in sections 2.3/2.4. We don't do this in prop224 yet, but I think it's useful because figuring out the torrc format now will help us understand if the scheme we are making is useful.
Here is a rough proposed UX for prop224 client auth, using Nick's idea from the top post of this thread. FWIW, I've used the same torrc option naming as we currently have but we should probably introduce new ones.
-- Hidden Service configuration
A hidden service uses the following torrc line to specify authed clients:
HiddenServiceAuthorizeClient <auth-type> <client-name>,<client-name>,...
If this option is configured, Tor generates client authorization data and creates a new "hs_client_auth.txt" file which contains lines with the following format:
client-name <client-name> NL HidServAuth <onion-address> <desc-x25519-privkey-b64> <intro-ed25519-privkey-b64> NL
where <client-name> is a nickname for the authed client, <desc-x25519-key-privb64> is an x25519 private key used to generate descriptor encryption keys (as Nick specified in top mail), and <desc-ed25519-privkey-b64> is an ed25519 private key used to perform the INTRO1 authorization protocol (as specified in section 3.4.2 of prop224).
e.g. client-name alice HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion 2vMVLDEAu+rc0rXFONpnor9mfG5xj0ovSh+YWIvOAvQ= qtXjslfyvPokRGFkzGnTXK7ICUNnoFyQRMORN/Zn4ss= client-name bob HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU= client-name charlie HidServAuth a1uik0w1gmfq3i5ievxdm9ceu27e88g6o7pe0rffdw9jmntwkdsd.onion /ADODiu4Dq6n+Oc5PGkmWmS72OEO9J46DTIWh8Omkck= QlQf+Bsukgjp8iGbdCuCihHHrbp6csN3yDFe8SSaTXU=
The idea here is that HS operators find the right HidServAuth line and paste it to their clients out-of-band, who then copy pastes it into their torrc file (or ideally plug it through tor browser in the future).
I think we should discourage people handing around shared private keys.
In particular, it's poor UI for the hidden service to generate private keys that only the user should know.
And it's even worse UI for the hidden service to take private keys as input - it should only ever take the public keys as input, even if we decide that it should generate the private keys for clients, it should not need to keep them around.
We should also make it possible for clients to provide their own private keys. We should introduce a keygen command for clients which generates a "HidServAuth" line, and then they can pass it to the HS operator, who puts it in their hs_client_auth.txt. Unclear what's the best UX way to do this; probably it should be a tor browser utility or sth…
I really do think this should be the default. Otherwise, the HS operator knows the private keys. (Although I don't think this breaks much, conceptually, it looks bad.)
I definitely agree it conceptually looks bad and/or dump for the hidden service to generate private keys and pass them to its users, even though it probably does not really affect security that much. Let's try to think of alternatives:
a) Clients securely generate keypairs and pass their pubkeys to the HS.
This is basically the SSH authorized_keys model, and it looks like the conceptually right way of doing this, but this definitely changes the UX in a major way.
I think the most painful thing here is that we will need to introduce a client-side keygen utility that will generate these keypairs, and present them to the user. It's unclear how we would do that, and it's extra engineering and UX analysis, since we need to assume that HS clients are not tech savvy and do not understand what public/private keys are.
Also, it means that clients need to _securely_ send credentials to the HS operator
The impact of clients sending the public keys in plain text is that an adversary who reads them can impersonate the HS to the client (if the client does not check the HS address). An adversary who modifies them can deny the client access to the HS (if the HS address is known), or impersonate the HS to the client (if the HS address is modified at the same time).
The impact of HSs sending the private keys in plain text is that an adversary who reads them can impersonate the client to the HS (unconditionally). An adversary who modifies them can deny the client access to the HS (if the HS address is known), or impersonate the client to the HS and the HS to the client - a man-in-the-middle (if the HS address is modified at the same time).
So from a security perspective, transferring public keys tends to be safer than transferring private keys. There would have to be a strong UX counter-argument.
and then they need to _wait_ till the HS operator adds those creds to Tor, before they are able to visit the HS. Till the HS operator adds their creds to Tor, authed client connections to the HS will fail silently since there is no NACK from the service and they will just be unable to complete rendezvous. We should probably speak with people that use client auth to tell us if this UX will break their model.
b) We can change the client auth methods to use symmetric keys, instead of assymetric keys. This way we avoid passing private keys to users.
No, the symmetric key *is* the secret key that needs to be protected. It can be just as sensitive as the private key.
The impact of HSs sending the symmetric keys in plain text is that an adversary who reads them can impersonate the client to the HS (unconditionally). An adversary who modifies them can deny the client access to the HS (if the HS address is known), or impersonate the client to the HS and the HS to the client - a man-in-the-middle (if the client does not check the HS address).
This might be a plausible way forward and potentially worth exploring.
For descriptor-level authorization, using symmetric keys is straightforward since we just need to do the same thing that we are now doing in rend-spec.txt (it's basically the scheme I posted in https://lists.torproject.org/pipermail/tor-dev/2016-November/011617.html)
For intro-level authorization, prop224 suggests we use ed25519 signatures for clients to prove ownership of their private key. We could perhaps switch those signatures to be MAC tags, so that we can perform those with symmetric keys.
What else can we do here? And am I perhaps overthinking of the UX issue here?
Without actual use cases, it will be hard to decide whether the complexity of an asymmetric scheme is worthwhile.
It certainly is for the user that wants to identify themselves uniquely to the HS, and ensure they control their credential.
For all other cases, a password or symmetric key is sufficient.
It's worth mentioning that the underlying implementation can use x25519 keys, and we can simply change how they are derived: * a public key supplied by the client, * a private key sent by the HS to the client, and transformed into a public key by the HS (this provides the same level of security as a symmetric key) * a password transformed into a private key by both client and HS using a KDF, and transformed into a public key by the HS (this is essentially a symmetric key).
T
George Kadianakis desnacked@riseup.net writes:
Also, it means that clients need to _securely_ send credentials to the HS operator and then they need to _wait_ till the HS operator adds those creds to Tor, before they are able to visit the HS.
One thing that might help here is Brian Warner's "magic wormhole" (http://magic-wormhole.io) -- which supports Tor. This would answer the "how to securely communicate the key" part, at the expense of both parties needing to be online at the same time. Basically, instead of exchanging the HS credentials directly, you'd share a "wormhole code" which is a SPAKE2 one-time password.
If, for example, a controller library like txtorcon added support for this, the HS operator (Bob) would run some command on their side ("invite alice") which would add credentials for Alice to Tor (via ADD_ONION_CLIENT or something) and give Bob a "wormhole code". Bob gives the code to Alice (ideally securely, but not nearly as critical here as with "actual" keys), who would run something app-specific on their side (e.g. "accept invitation") and type in the code they were given. The command running on Bob's side would pass the actual HS credentials (via the now-established wormhole) to Alice's running application (which then also would use some controller command to add the client credentials to their Tor instance).
So, neither Alice nor Bob ever actually see any keys at all.
We should probably speak with people that use client auth to tell us if this UX will break their model.
+1 It would be great to know how people actually exchange these things currently :)
Regarding the API / interface for communicating client-keys for hidden- services .. I thought we were encouraging ADD_ONION based services?
Personally, I think using the filesystem as "an API" isn't very good. From a controller standpoint, it's *way* simpler to use ADD_ONION properly than on-disc services (i.e. via SETCONF) because directory permissions, file permissions etc have to line up and it's not immediately clear if the files will always for-sure be on-disc when the SETCONF command says OK. (Also, you have to deal with the one-shot nature of SETCONF and order-matters configuration options)
On the disadvantage side, this means any applications using these services are then responsible for their own key-management.
In any case, something like growing an "ADD_ONION_CLIENT" command or similar might be way easier to understand and implement.
A flow might look something like this:
- client creates a key(/pair) in tor-browser or whatever - client sends it to service operator ("exercise to the app-developer"?) - operator uses their controller to run "ADD_ONION_CLIENT" - ??? - profit!
Definitely out-of-scope for "ng hidden-services", but it would also probably be nice to have more separation in the control-protocol. Right now, you get the authority to do anything at all -- but maybe you'd like to give an application *just* the authority to "add hidden services and/or clients". You can use a control-port-filtering thing (e.g. roflcopter) to get something like this, but ... not ideal (and not really the same as being able to grant limited authority to an application).
I'm thinking here of scenarios where you have an application that wants to "use Tor" to do service-stuff -- so "just edit the config" isn't a satisfying answer at all. Also, having every app launch its own Tor instance (which is about the only answer currently) seems bad.
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hello,
I worked some more on prop224 client authorization. I have a draft torspec patch at prop224_client_auth_3 in my repo: https://gitweb.torproject.org/user/asn/torspec.git/commit/?h=prop224_client_...
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
I also added some more high-level details on client auth in the intro section, which should be useful to people who read the proposal for the first time.
In the appendix, I added a section with some rough ideas on how the torrc configuration could work, and how a control port interface could work. This is just a sketch so far, and we can get more specific as we get closer to implementation fot this feature.
Finally, I've been assuming AES128 for the STREAM() cipher so that the size computations performed earlier on this thread are still accurate. If we want to pump it to AES256, the IVs and the descriptor cookie ciphertexts will double in size for each authorized client. If we actually want to go with AES256, we need to peform new computations about the padding and max descriptor size. If you people like the rest of the patch here, I can do the calculations again.
Cheers!
On 15 Nov (16:29:33), George Kadianakis wrote:
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
=============
Let every client generate a curve25519 keypair, and tell the hidden service operator about the public key. This keypair takes the place of the long-term shared secret. For some client C, denote the secret key as x_X and the public key as X_C.
For every descriptor, the hidden service generates a fresh keypair <y, Y>, and includes Y in the the outer encrypted layer.
Now, for each client, the hidden service computes curve25519(X_C, y) and uses this as the input for two KDF functions. Call these outputs K1_C and K2_C. The hidden service generates an auth-client line for each client as follows:
"auth-client" SP client-id SP encrypted-cookie
This is the same as in George's proposal, except that client-id is derived from a truncated version of K1_C, and the encrypted-cookie portion is encrypted based on K2_C.
When the client receives the descriptor, it decrypts the outer layer, then sees the value of Y that the hidden server advertised. It computes curve25519(Y, x_c), and derives K1_C and K2_C. It uses K1_C to find the appropriate entry on the list, and then uses K2_C to decrypt it and find the descriptor cookie.
=============
Advantages:
- managing public keys can be easier than managing shared secrets.
- The encoding is slightly shorter, since no IV is needed, since K2
is different every time.
- probably others?
Disadvantages:
- Curve25519 costs more computationally than non-public-key operations
- probably others?
Hello,
I worked some more on prop224 client authorization. I have a draft torspec patch at prop224_client_auth_3 in my repo: https://gitweb.torproject.org/user/asn/torspec.git/commit/?h=prop224_client_...
I personally like this very much. Apart from minor syntax issues and spacing, I think this scheme is getting to a point where it's simple and efficient.
I think the introduce auth section (INTRO-AUTH) needs to be edited more though because we are still mentionning password and ed25519 authentication but I understand that waiting until we all agree on the client auth mechanism is wise.
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
Yes, I believe this is fine. Note that tor-keygen tool is getting another _very_ important use case here that is the key generation on client side.
I also added some more high-level details on client auth in the intro section, which should be useful to people who read the proposal for the first time.
In the appendix, I added a section with some rough ideas on how the torrc configuration could work, and how a control port interface could work. This is just a sketch so far, and we can get more specific as we get closer to implementation fot this feature.
Looks good to me. The naming will _most_ probably change as we already have those names in torrc with a different API but the format to me is simple and easy to use.
And the control port commands are _very_ important as it would allow TBB to easily add client auth with some UI instead of hot hacking torrc file. And this would be a giant step foward in usability of client auth.
Finally, I've been assuming AES128 for the STREAM() cipher so that the size computations performed earlier on this thread are still accurate. If we want to pump it to AES256, the IVs and the descriptor cookie ciphertexts will double in size for each authorized client. If we actually want to go with AES256, we need to peform new computations about the padding and max descriptor size. If you people like the rest of the patch here, I can do the calculations again.
Which might also change our maximum size of 40k we put there.
One note. I haven't seen a maximum value of client we allow. Did I miss it or it's also maybe too early to put there as we are still discussing the specifics. Which makes me think that maybe that 40k limit is also a bit arbitrary for now based on that.
Thanks for the great work! David
Cheers! _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
On 18 Nov. 2016, at 03:52, David Goulet dgoulet@ev0ke.net wrote:
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
Yes, I believe this is fine. Note that tor-keygen tool is getting another _very_ important use case here that is the key generation on client side.
The tor-keygen tool is not currently included in the Tor Browser bundle. So we would have to add it (or provide an alternate method) for Tor Browser users.
T
On 18 Nov (08:27:53), teor wrote:
On 18 Nov. 2016, at 03:52, David Goulet dgoulet@ev0ke.net wrote:
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
Yes, I believe this is fine. Note that tor-keygen tool is getting another _very_ important use case here that is the key generation on client side.
The tor-keygen tool is not currently included in the Tor Browser bundle. So we would have to add it (or provide an alternate method) for Tor Browser users.
It also does not really exists :). But we have a ticket for it and it's very important also for HS offline keys!
And yes, I like you idea that TBB should have it included coupled with a nice UI for HS auth.
Cheers! David
T
-- Tim Wilson-Brown (teor)
teor2345 at gmail dot com PGP C855 6CED 5D90 A0C5 29F6 4D43 450C BA7F 968F 094B ricochet:ekmygaiu4rzgsk6n xmpp: teor at torproject dot org
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
On 18 Nov. 2016, at 09:20, David Goulet dgoulet@ev0ke.net wrote:
On 18 Nov (08:27:53), teor wrote:
On 18 Nov. 2016, at 03:52, David Goulet dgoulet@ev0ke.net wrote:
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
Yes, I believe this is fine. Note that tor-keygen tool is getting another _very_ important use case here that is the key generation on client side.
The tor-keygen tool is not currently included in the Tor Browser bundle. So we would have to add it (or provide an alternate method) for Tor Browser users.
It also does not really exists :). But we have a ticket for it and it's very important also for HS offline keys!
Oh right, I had it confused with tor-gencert.
And yes, I like you idea that TBB should have it included coupled with a nice UI for HS auth.
And the Tor Expert Bundle (Windows) so people can run HSs on Windows using it.
T
David Goulet dgoulet@ev0ke.net writes:
[ text/plain ] On 15 Nov (16:29:33), George Kadianakis wrote:
Nick Mathewson nickm@torproject.org writes:
<snip>
Hello,
I worked some more on prop224 client authorization. I have a draft torspec patch at prop224_client_auth_3 in my repo: https://gitweb.torproject.org/user/asn/torspec.git/commit/?h=prop224_client_...
I personally like this very much. Apart from minor syntax issues and spacing, I think this scheme is getting to a point where it's simple and efficient.
I think the introduce auth section (INTRO-AUTH) needs to be edited more though because we are still mentionning password and ed25519 authentication but I understand that waiting until we all agree on the client auth mechanism is wise.
I ended up using the x25519 scheme described above by Nick.
I also ended up dodging the UX questions raised on this thread, by only specifying the Tor protocol level details, and leaving the out-of-band HS<->client protocol mostly unspecified. I believe that this out-of-band protocol and configuration details can be figured out in the future, and we should not block on them right now.
Yes, I believe this is fine. Note that tor-keygen tool is getting another _very_ important use case here that is the key generation on client side.
I also added some more high-level details on client auth in the intro section, which should be useful to people who read the proposal for the first time.
In the appendix, I added a section with some rough ideas on how the torrc configuration could work, and how a control port interface could work. This is just a sketch so far, and we can get more specific as we get closer to implementation fot this feature.
Looks good to me. The naming will _most_ probably change as we already have those names in torrc with a different API but the format to me is simple and easy to use.
And the control port commands are _very_ important as it would allow TBB to easily add client auth with some UI instead of hot hacking torrc file. And this would be a giant step foward in usability of client auth.
Finally, I've been assuming AES128 for the STREAM() cipher so that the size computations performed earlier on this thread are still accurate. If we want to pump it to AES256, the IVs and the descriptor cookie ciphertexts will double in size for each authorized client. If we actually want to go with AES256, we need to peform new computations about the padding and max descriptor size. If you people like the rest of the patch here, I can do the calculations again.
Which might also change our maximum size of 40k we put there.
One note. I haven't seen a maximum value of client we allow. Did I miss it or it's also maybe too early to put there as we are still discussing the specifics. Which makes me think that maybe that 40k limit is also a bit arbitrary for now based on that.
Hello,
I understand your concern, and hence I performed the descriptor size calculations again based on the encoding format of the latest branch (prop224_client_auth_3). You asked for it!
First of all, in the end of this email I inline a real prop224 HS descriptor based on the prop224_client_auth_3 torspec branch, and _without any encryption_. Use that descriptor as a guidance, or to double-check my calculations.
To cut to the chase, here are my current recommendations regarding descriptor padding and maximum size:
- The superencrypted blob (between "superencrypted\n-----BEGIN MESSAGE-----" and "-----END MESSAGE-----") should be padded with NULs to the nearest multiple of 10k bytes before it gets encrypted and base64ed. This is the same as what is specified in prop224_client_auth3.
- Max total descriptor size accepted by HSDirs is 50k bytes. We should also control this with a consensus parameter, in case it ever ends up being too small or too big. In prop224_client_auth_3 it is suggested that the max size should be 40k bytes, but actually I think 50k bytes is a better number given the new scheme and the 10k padding. Please see below.
- We always add fake "auth-client" entries to reach the nearest multiple of 16.
Now here are some observations:
a) The superencrypted blob gets padded to nearest multiple of 10k bytes before it gets base64ed. If you base64-encode 30k bytes you get back 40k base64 bytes, which is basically the max size of superencrypted blob we can support if the max descriptor size is 50k bytes. The remaining 10k bytes are left for the unencrypted header (and footer) of the descriptor which in the example below is 400 bytes.
b) Every new intro point block adds about 615 bytes to the blob, whereas legacy intro points add about 870 bytes to the blob. For the sake of calculations, let's average that to 750 bytes per intro point.
Every authed client adds 75 bytes to the superencrypted part of the descriptor. Every block of 16 authed clients adds 75*16 = 1200 bytes.
If we used AES-256, the IV and ciphertext would double in size, and each authed client line will be 115 bytes. Every block of 16 authed clients would be 1840 bytes. In the final section I give some figures for the case where we use AES-256.
Now let's calculate some useful numbers:
- Given the suggested limits above, we want to learn how many authed clients and intro points we can fit in HS descriptors. Let's start by calculating the max number of clients/IPs we can ever support.
The max allowed size of a superencrypted blob is 30k bytes (see (a) above). Here are three examples of information we can fit in 30k bytes: * In 30k bytes, we can fit 3 intro points and 352 authed clients using AES-128 * In 30k bytes, we can fit 10 intro points and 240 authed clients using AES-128 * In 30k bytes, we can fit 20 intro points and 144 authed clients using AES-128
So the above figures are the max HS settings given the 50k max descriptor size limit. If we make the max desc size a consensus parameter, we can bump it up if in the future we think it's a severe limitation.
- It's worth noting that the setups above require a superencrypted blob of size 30k bytes. Such a big descriptor will stand out from the rest! That's because most hidden services will have a superencrypted blob of size 10k, since that's big enough to fit 3 intro points and 16 authed clients (about 3.5k bytes, leaving about 6.5k bytes of padding).
The next question here is how much info can we fit in a superencrypted blob of size 10k, so that our descriptor remains in the biggest anonymity set. Here are some figures: * In 10k bytes, we can fit 3 intro points and 80 authed clients using AES-128 * In 10k bytes, we can fit 6 intro points and 48 authed clients using AES-128 * In 10k bytes, we can fit 11 intro points and 16 authed clients using AES-128
As another piece of information, this means that most hidden service descriptors will be about 14k bytes in size (10k bytes encoded in base64 + a 500 bytes header/footer).
Now let's draw some conclusions:
- I feel that the max settings imposed by the 50k max size limit, will satisfy most crazy hidden service use cases that someone might have wrt scalability or number of authed clients. It can support up to 350 authed clients, and 20 intro points. We should increase the max size limit, if we want to support more advanced use cases.
- I also feel the configurations that fit in the default descriptor (of 10k bytes blob) will probably satisfy most hidden service use cases out there as it can support up to 80 authed clients, and up to 11 intro points. The anonymity set of those hidden services descriptors will be good wrt snooping HSDirs
- Giant hidden service descriptors will stand out and their anonymity set will likely be small. I think such giant hidden services should perhaps split their info to multiple descriptors using some sort of stealth-auth mechanism (where they give different onion address to different clients). Alternatively, we should change our padding rules, or always pad to max descriptor size.
- Now finally, let's consider the possibility that we do AES-256 instead of AES-128, which will basically roughly double the size of each "auth-client" line. For this case, I attach updated figures like the above ones but where we use AES-256 instead of AES-128: * In 30k bytes, we can fit 3 intro points and 224 authed clients using AES-256 * In 30k bytes, we can fit 10 intro points and 144 authed clients using AES-256 * In 30k bytes, we can fit 20 intro points and 80 AES-256 authed clients using AES-256 * In 10k bytes, we can fit 3 intro points and 32 AES-256 authed clients using AES-256 * In 10k bytes, we can fit 10 intro points and 16 AES-256 authed clients using AES-256
AFAIK, the security of AES-128 is basically the same as that of AES-256: the are both way unbreakable by brute force and there are no known attacks faster than brute force (there are some crazy related keys attacks for AES-256). The main reason to consider AES-256 instead of AES-128 would be in case there is a quantum computer advanced enough to be able to brute force using Grover's algorithm (which would reduce the security of AES-128 down to 64 bits).
Personally, I feel OK using AES-128 here given our space limitations. We can always upgrade in the future by adding a new "desc-auth-type". If people don't feel this way, I can be persuaded to use AES-256.
Please let me know if I forgot something, or my calculations/reasoning is wrong. Cheers!
Closing with an unencrypted prop224 descriptor:
hs-descriptor 3 descriptor-lifetime 180 descriptor-signing-key-cert -----BEGIN ED25519 CERT----- AQgABkVaAYyweSjAkVRKpNSaTLH++QbDfBJIoMBk7hQo5HBHEQO3AQAgBAB1BKGr Q6+Ykkjh8lLji19np8Egbh+pOUmvs4FkY+UskQJoq1rF5vdvu4v1gl3imqIrFuw4 Rxxf/0QsfJNba9oy8OgP0/tvSwVJpeqAcpLGl2DgaJKC8SmfBOfeSRSo1g0= -----END ED25519 CERT----- revision-counter 42 superencrypted -----BEGIN MESSAGE----- desc-auth-type x25519 desc-auth-ephemeral-key DZxD+KN/tb7CRNqtls6r1Y/lPWjY6IvXSU3J1mWXF0M= auth-client iXh2oNSByYc= keAvG5ANocwmMYnhZLWlUw== VVqf1v5Q1g5ybIC814Cm5Q== auth-client 6KO0XaQxp0s= 2KGh7K10bjV9BK2CimWfJQ== lSrM70nNmkkjdf/r6ONH1Q== auth-client UUnbOeDc3eQ= u6xgtYEk7n8ReNzSxcBv4w== J0Wsxxpl5yuo3cVzSP3V2w== auth-client dG4mA4iP/p8= N1l5KlVJFGtJR3Q+7rxRMQ== BaBEB2YsExR39tVSwXvY0A== auth-client fqofw7ytKGg= v7txoPRfoO61SQ3zS3wcXQ== qAAcoyAaItrgKJUOg/Lybg== auth-client fpGNjf1PM6Y= 6S+fRJ6BiN3u8XyDN1aF9w== 3sHtIM1+6E2VKKWfu6fsbg== auth-client u7R+e+yCKpM= C+qGWQL49CswN5NDpxLJ+w== ESyttpFX/N2TML4Es4RtKg== auth-client /AkfV7OQCSc= Zi8hiaehNYHcksV/HCANjQ== mFPKGs4tZhIevYvwANFSDQ== auth-client yZw7wK8rn1g= cGV1RkvbZN+Ygu/yQjT41Q== hk85M3ubU7ztdZBesKq7FQ== auth-client x8fN+ntscK0= Tbdg1EC8Bx4Sl4O8KdSs0g== v+BhwLJW4q+UZ46SNhxBtQ== auth-client v6lVDNLur/E= /WkCfpqmXksGrVcwlS2OYQ== bEiVRcxuBAZOgn53UovU7w== auth-client nFlDLWH+jrw= Kmnoz6XleSSg1j8ZIDzTJw== ZfKncy7BOs7255TN+vMptw== auth-client wlKR7bGdA/4= zLfiSqDaMRLTfh0Anh4AAA== 3LfQfjs5kCzzZ0oqdKfGdw== auth-client //nEhMuRPp4= SUUGpb+mfmvyg4cLV/eTlA== Vk3aGKmQ5OHwvFZ+mOOt9A== auth-client 9KQPP4iufV0= GwPRcpT8ZPRL4+850iBeTA== kQb3p6wecHbHmnuOkweKrQ== auth-client uNG2Gcd164k= vVGtw66XLhC3BBtvvh/7wQ== MkunVMQIkIlu+jk65v/jKg== encrypted -----BEGIN MESSAGE----- create2-formats 2 authentication-required ed25519 single-onion-service introduction-point AQAGAQIDBCMp auth-key -----BEGIN ED25519 CERT----- AQkABkVxASfaZku9bNjuRH8mB0dwa3jSwy3gMXZWLZPAN/CD76ofAQAgBAB1BKGr Q6+Ykkjh8lLji19np8Egbh+pOUmvs4FkY+UskYskSuK0jEJVBQwcRDvFDmxoC2BU IgcScfXfSqDm4GPNMYw0eZXWrPamRjQ28x42XL2vgOdRaTdO+zN52dqKqgw= -----END ED25519 CERT----- enc-key ntor LV4gZ7/ozXVOsscwv64hSKGP5F7IG1/igXY4EFOm4jU= enc-key-certification -----BEGIN ED25519 CERT----- AQsABkVxAYyweSjAkVRKpNSaTLH++QbDfBJIoMBk7hQo5HBHEQO3AQAgBAA0aSb+ m6u/CKV8M2GfCho+JRUWc1M6wRSg/39oRo2S3rFRvabgkWXfYpRRtUYRHuiVTHHR 6xjitgcvi0nu+Bsfk7oxV6TPJ1TGBYSCk4D3MA+RmaF+Boccm/ta8C3TFgQ= -----END ED25519 CERT----- introduction-point AQESJgAAAAAAAAAAAAAAAAAAASMp auth-key -----BEGIN ED25519 CERT----- AQkABkVxAbKdovMTbxsO19ksN86mhh5qgqj0aLCuESujwMSY0+hNAQAgBAB1BKGr Q6+Ykkjh8lLji19np8Egbh+pOUmvs4FkY+UskThy9RGDqvApdyrPh+Ws9cPRaRqw OU65kRFkbbtPfk1+zgDKXNRP1Aef4rQOuTuXnGyKGq/FJZvgZZ6FG6BSTQA= -----END ED25519 CERT----- enc-key ntor 8v58PYUwEPScIJquczdHMmXGLO4lWS2mYEWxtA+OYEY= enc-key-certification -----BEGIN ED25519 CERT----- AQsABkVxAYyweSjAkVRKpNSaTLH++QbDfBJIoMBk7hQo5HBHEQO3AQAgBADrWgPc /9QG8FklzT0QD3+OZFGdIqyQn6yZ2YJ4V1YXAlCKbN+YcoE1Vbga1gg/dl9fvKR3 6+QBPcm4MoXA5xYEC4zehU1x0+nlHsZGowM/R/RQNenXT+dtrRauw9Wtnw0= -----END ED25519 CERT----- introduction-point AQIUMDI5OUYyNjhGQ0E5RDU1Q0QxNTc= auth-key -----BEGIN ED25519 CERT----- AQkABkVxAZe3yC3t81HG9D2Hih/FnRsa8nIASXq0kmpZdiMPuYSAAQAgBAB1BKGr Q6+Ykkjh8lLji19np8Egbh+pOUmvs4FkY+UskUQgN18iLDLcncgANUPzMa4lNKik 75XvFdV7Rnw8T2ZLuOE+wtTv9LDsTbrK4i7JGM2gdpVar3QXQiHvIrcs8AA= -----END ED25519 CERT----- enc-key legacy -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAN0Ofcf4S7QBbkYqiGoMGe3Dq5ud3dVonBkbNnKBrgnaQuDyl49EBboY MPqlwfNb4plsVYe1GTvQVLC+bIZx/4NjSvm1/IIfIMaZsnI9HSjo5UKBIWVxx/h4 O9vKzPMx2XHe4vTkAEikJKGgq0RSq/IhCVrcmif5AHC5WSLMzPJXAgMBAAE= -----END RSA PUBLIC KEY----- enc-key-certification -----BEGIN CROSSCERT----- jLB5KMCRVEqk1JpMsf75BsN8EkigwGTuFCjkcEcRA7cABkVxgKuLLNWR1F7JMfNn 7OsljmbS/QeinkTEm6KC0QSP8SVelpxGfu5oRgP9ubC6G0+qOBXrMysnLz8fnFDS id2IjCqUwN6K2LZ3lPqJjzDnCcPf1NR/mNqwbOD4BKlNEIjo92G8S61WarCN/eRB Wyq+as6KMvtC7vfq5FJoKFEy88N7 -----END CROSSCERT----- -----END MESSAGE----- -----END MESSAGE-----
I feel that the max settings imposed by the 50k max size limit, will satisfy most crazy hidden service use cases that someone might have wrt scalability or number of authed clients. It can support up to 350 authed clients, and 20 intro points. We should increase the max size limit, if we want to support more advanced use cases.
I also feel the configurations that fit in the default descriptor (of 10k bytes blob) will probably satisfy most hidden service use cases out there as it can support up to 80 authed clients, and up to 11 intro points. The anonymity set of those hidden services descriptors will be good wrt snooping HSDirs
Giant hidden service descriptors will stand out and their anonymity set will likely be small. I think such giant hidden services should perhaps split their info to multiple descriptors using some sort of stealth-auth mechanism (where they give different onion address to different clients). Alternatively, we should change our padding rules, or always pad to max descriptor size.
I understand what I'm saying below might be a bit far fetched but while we're brainstorming on things, I thought I'd just throw this out...
I think it would be interesting to see things like onion-balance get integrated into this setup at some point in the long run, so if there's a giant onion service, it would automatically scale after a certain amount of clients or requests. I haven't thought much about how it can work in auth mechanism but I find it an interesting subject to think about. Specially if we want to mainstream the heavy use of onion services.
Kudos for working on such important properties of Tor.
Cheers,
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
OK people,
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
The only real changes from `prop224_client_auth_3` is that it increases the max descriptor size to 50k, and it removes the username/password intro-level authorization.
Please let me know of anything that seems off, or anything that can make the proposal more readable. Otherwise, we should merge this upstream and move forward with fixing the already merged prop224 HSDir code.
Thanks!
Hello,
George Kadianakis wrote:
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
OK people,
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
The only real changes from `prop224_client_auth_3` is that it increases the max descriptor size to 50k, and it removes the username/password intro-level authorization.
Please let me know of anything that seems off, or anything that can make the proposal more readable. Otherwise, we should merge this upstream and move forward with fixing the already merged prop224 HSDir code.
Thanks!
It is very good. The hard limit raised to 50k is justified, and excellent to remove the username/password intro-level authorization.
I would like to state, since I seen it in older posts on this thread, that I dislike the idea of generating at client side low entropy ed25519 key pairs based on simple passwords. It may sound simple and good from UX point of view, but we are decreasing the security of a very secure auth scheme with it and enabling an over-the-hand practice that keys come from client to HS and not vice-versa.
My 2 cents here are that keys should always be generated randomly by the HS server, and distributed to clients (I think it's over the hand for the HS server to use keys generated by clients, because the purpose is for the HS server to secure itself against _everyone_ except some users). For this I am thinking of a very simple tool, that reads the auth-client data file in $DataDirectory/ that will just show a table like:
[ADD A CLIENT] HS | client | pubkey | privkey | notes| actions | date [revoke] [change key]
(of course available in console mode also with keyboard shortcuts for commands)
Since we have no real reason to see the privkey of a client ever again at the HS server side (unless the client loses it, but in this case we regenerate fresh keys for security reasons), client privkeys can not be written to disk at HS server side.
For saved authorized clients we display "******" on privkey column. When a client is added, highlight the row with red or something signaling privkey distribution phase and only keep the keys in RAM. After the privkey has been copied and user checked a box with 2 confirmation dialogs that state something like "I have distributed the key to the client and i understand that it will be permanently deleted, and I could need to regenerate the key for this client if he didn't get it." save the pubkey, client name, etc to file and permanently delete the privkey.
If anything happens (client manager app is closed, power failure, reboot, etc.) start over with new key pair. Same when a key for a client needs to change, we only keep the client name from the table and create fresh key following the same protocol.
The client mode of the auth tool will look like:
[ADD An ONION] HS | notes | privkey | actions | date [delete] [change key]
(of course available in console mode also with keyboard shortcuts for commands)
Here the auth tool will only append/modify data from client's torrc.
It's OK to save the privkeys in plain text at client side from my point of view. We could do encryption with a passphrase but it will be annoying: either the auth management tool needs to be a plugin of Tor Browser so that it asks for the passphrase only one time on start / first connection (otherwise is _very_ annoying for UX) - not everyone uses Tor Browser and more important not everyone uses HS for web browsing - maybe it's a ssh server, either the tool itself needs to run in background all the time.
Hi!
Sorry to be late to the party. I still haven't seen UX concerns fully addressed, and I think we should not create a specification that will make the life of our users harder if we can avoid it.
s7r:
George Kadianakis wrote:
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
I would like to state, since I seen it in older posts on this thread, that I dislike the idea of generating at client side low entropy ed25519 key pairs based on simple passwords. It may sound simple and good from UX point of view, but we are decreasing the security of a very secure auth scheme with it and enabling an over-the-hand practice that keys come from client to HS and not vice-versa.
I hope we can find a balance between “a very secure auth scheme” that will be too cumbersome to use for most users and “a secure and usable auth scheme”.
I've been hoping we could get a nice UI in Tor Browser to access authenticated onion services for a while now (#8000). The difficult part UX-wise is that there is no way to differentiate between an onion service that is either non-existant, temporary unavailable or authenticated. (But it's good for security, so let's keep things that way.)
How are users expected to give enter the private key in Tor Browser? Does the key have to be saved on disk? What should I have to do to browse an authenticated onion service when running under Tails without persistence enabled?
I don't see how to streamline support for an amnesic system if I have to generate a unique keypair that I need to give to the onion service owner beforehand.
Should we draw inspiration from miniLock? https://minilock.io/files/HOPEX.pdf (see slide 35)
If I try to think of my experience as an admin, I see several cases where it would be much easier to give authentication token to users myself. User story:
Elena has set up an Etherpad instance on her private server. She generates a handful of access codes before going to meet the newly formed copwatch chapter. After the end of the meeting, she can give out a piece of paper to all attendees so they can access the minutes and write up reports together in the future.
You really don't want to have all attendees bring their computer or require them to meet with Elena at a later time.
Hope that helps,
On 06 Dec (17:23:10), Lunar wrote:
Hi!
Sorry to be late to the party. I still haven't seen UX concerns fully addressed, and I think we should not create a specification that will make the life of our users harder if we can avoid it.
I believe it can be addressed by a good UI in TBB mostly to fit this client authorization proposal. Answers below.
s7r:
George Kadianakis wrote:
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
I would like to state, since I seen it in older posts on this thread, that I dislike the idea of generating at client side low entropy ed25519 key pairs based on simple passwords. It may sound simple and good from UX point of view, but we are decreasing the security of a very secure auth scheme with it and enabling an over-the-hand practice that keys come from client to HS and not vice-versa.
I hope we can find a balance between “a very secure auth scheme” that will be too cumbersome to use for most users and “a secure and usable auth scheme”.
I've been hoping we could get a nice UI in Tor Browser to access authenticated onion services for a while now (#8000). The difficult part UX-wise is that there is no way to differentiate between an onion service that is either non-existant, temporary unavailable or authenticated. (But it's good for security, so let's keep things that way.)
How are users expected to give enter the private key in Tor Browser? Does the key have to be saved on disk? What should I have to do to browse an authenticated onion service when running under Tails without persistence enabled?
We thought about this a bit (maybe not in depth) but the idea here is that an HS operator will have a choice between creating an authentication token for a specific client or add one that a client gave it to her.
For a client, we kept the "token" to be a one liner containing the key material and an identifier. So it becomes a matter of "How the client generates that token?" and "How it is exchanged between client and operator?" I think the way to go here is for sure an integration in TBB.
First option would be for a user to enter a password and the keys are derived from it and we output the one line that the user should give to the HS operator. If the HS operator already have that line configured in, well great, it addresses the Tails use case where you move around and you simply need to input your password to get the right token that you've already gave to the HS.
The second option would be to "Generate token for me", output the line and give out-of-band to HS operator that one liner.
And the third option would be to "Enter token here" which is the case where HS operator gives out token to client.
All those are a UI challenge but I think will be _great_ improvement to the current state of things but they are all on TBB side.
One thing that we unfortunately can't solve is the "give token to HS operator automagically", it has to be out-of-band else we are getting into another world of complexity. HOWEVER, we could think of a proposal to have some sort of "Auth Server Transport" support which you could tell your tor to fetch token from that "auth server" but that is some big piece of work.
I don't see how to streamline support for an amnesic system if I have to generate a unique keypair that I need to give to the onion service owner beforehand.
To be honest, it would be quite amazing to pull off a TBB UI for this at the same time as we roll out prop224 in a tor stable :) with the use case of amnesic system.
Should we draw inspiration from miniLock? https://minilock.io/files/HOPEX.pdf (see slide 35)
If I try to think of my experience as an admin, I see several cases where it would be much easier to give authentication token to users myself. User story:
Elena has set up an Etherpad instance on her private server. She generates a handful of access codes before going to meet the newly formed copwatch chapter. After the end of the meeting, she can give out a piece of paper to all attendees so they can access the minutes and write up reports together in the future.
You really don't want to have all attendees bring their computer or require them to meet with Elena at a later time.
Yeah... the client token I've been talking about is a bit long actually but we have to to ensure some semblance of modern security that is ECC keys of 32 bytes.
However, what we could do server side is generate a client key associated with some keywords that if put in TBB UI would generate same client key (a bit like pond does with the words).
Thanks for the feedback! David
Hope that helps,
Lunar lunar@torproject.org
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Thanks Lunar for bringing this into discussion. See below.
David Goulet wrote:
On 06 Dec (17:23:10), Lunar wrote:
Hi!
Sorry to be late to the party. I still haven't seen UX concerns fully addressed, and I think we should not create a specification that will make the life of our users harder if we can avoid it.
I believe it can be addressed by a good UI in TBB mostly to fit this client authorization proposal. Answers below.
s7r:
George Kadianakis wrote:
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
I would like to state, since I seen it in older posts on this thread, that I dislike the idea of generating at client side low entropy ed25519 key pairs based on simple passwords. It may sound simple and good from UX point of view, but we are decreasing the security of a very secure auth scheme with it and enabling an over-the-hand practice that keys come from client to HS and not vice-versa.
I hope we can find a balance between “a very secure auth scheme” that will be too cumbersome to use for most users and “a secure and usable auth scheme”.
I've been hoping we could get a nice UI in Tor Browser to access authenticated onion services for a while now (#8000). The difficult part UX-wise is that there is no way to differentiate between an onion service that is either non-existant, temporary unavailable or authenticated. (But it's good for security, so let's keep things that way.)
How are users expected to give enter the private key in Tor Browser? Does the key have to be saved on disk? What should I have to do to browse an authenticated onion service when running under Tails without persistence enabled?
We thought about this a bit (maybe not in depth) but the idea here is that an HS operator will have a choice between creating an authentication token for a specific client or add one that a client gave it to her.
At client side, the private keys have to be saved on disk (in plain text if we want to provide a simpler UX, because either way I don't think we can make it as simple as we'd like).
For a client, we kept the "token" to be a one liner containing the key material and an identifier. So it becomes a matter of "How the client generates that token?" and "How it is exchanged between client and operator?" I think the way to go here is for sure an integration in TBB.
First option would be for a user to enter a password and the keys are derived from it and we output the one line that the user should give to the HS operator. If the HS operator already have that line configured in, well great, it addresses the Tails use case where you move around and you simply need to input your password to get the right token that you've already gave to the HS.
I agree here. This becomes a problem when the same user has multiple authenticated HSes. She has to either remember a different password linked to every authorized HS - which is bad for UX, either use a single password for all of them, to keep things easy. If users choose simple passwords, which people are inclined to do, brute-forcing the auth credentials for adversaries that know the onion hostname will become trivial and will defeat the purpose of authentication.
The second option would be to "Generate token for me", output the line and give out-of-band to HS operator that one liner.
And the third option would be to "Enter token here" which is the case where HS operator gives out token to client.
All those are a UI challenge but I think will be _great_ improvement to the current state of things but they are all on TBB side.
Yes, second and third options are not something human memorable or easily reproductive, and will not survive a re-install without backup or suite the 'amnesic' mode users.
Here's a wild idea:
We generate the key client side using a string of words, that are human memorable and when entered again will produce the same key. I think such a system would work at large scale. The key produced here will be the master key.
To solve the challenge of mapping onion hostnames to tokens, eliminate the need to use the same token for all authorized HS and also kind of fix the issue when we don't know which HS uses auth or not, we derive child keys from the master key for each onion hostname.
Client and server need to compute the same child key in every case, so the derivation key will be the HS full onion hostname itself.
Example: token for foo.onion = <master-key> -> <derivation-key: 'foo.onion'> token for abc.onion = <master-key> -> <derivation-key: 'abc.onion'>
Benefits: - users share a single master public key with servers which is easier and also use different credentials for each HS. They can even include it on business cards, email signatures, publish on their blog, you name it.
- there's no need to map each token with an onion hostname, Tor just does it by computing the right token for each HS (this can be cached for a session so that it's not computed over and over again).
- different tokens for every HS computed /used automatically and not even shown to the user, for a simple and easy UX.
- we know if the HS is non-auth, auth or offline: if we don't find a descriptor, it's offline. If we find a descriptor, we compute the child key and decrypt it (auth enabled) or just connect if it's non-auth. This requires computing child keys for every HS we try to connect to, but maybe it's worth it?
- no penalties on server side for revoking a client. Just delete the master public key. Same client can be re-added with the same master public key. When a client changes the master public key it's no different than all other mechanisms anyway so we lose nothing.
Cons: - a HS that has a client master public key can learn if the same client is also authorized for other HS that the address is _known_ . However, one can only learn this info, the auth cannot be defeated since only public key is known, not the private key which is used at client side to decrypt the descriptor.
While I think such a mechanism may be nice from UX point of view, I don't know if curve25519 supports it. It is possible and proven in practice with secp256k1 which is where I got the idea, but this requires a point of view from someone with deeper knowledge in crypto.
One thing that we unfortunately can't solve is the "give token to HS operator automagically", it has to be out-of-band else we are getting into another world of complexity. HOWEVER, we could think of a proposal to have some sort of "Auth Server Transport" support which you could tell your tor to fetch token from that "auth server" but that is some big piece of work.
I don't see how to streamline support for an amnesic system if I have to generate a unique keypair that I need to give to the onion service owner beforehand.
To be honest, it would be quite amazing to pull off a TBB UI for this at the same time as we roll out prop224 in a tor stable :) with the use case of amnesic system.
Should we draw inspiration from miniLock? https://minilock.io/files/HOPEX.pdf (see slide 35)
If I try to think of my experience as an admin, I see several cases where it would be much easier to give authentication token to users myself. User story:
Elena has set up an Etherpad instance on her private server. She generates a handful of access codes before going to meet the newly formed copwatch chapter. After the end of the meeting, she can give out a piece of paper to all attendees so they can access the minutes and write up reports together in the future.
You really don't want to have all attendees bring their computer or require them to meet with Elena at a later time.
Yeah... the client token I've been talking about is a bit long actually but we have to to ensure some semblance of modern security that is ECC keys of 32 bytes.
However, what we could do server side is generate a client key associated with some keywords that if put in TBB UI would generate same client key (a bit like pond does with the words).
This should be an option also. So the HS either generates a random key for a client either uses client's master public key to derive the child key. These need to co-exist at the same time, they are solid use cases.
George Kadianakis desnacked@riseup.net writes:
Nick Mathewson nickm@torproject.org writes:
[ text/plain ] Hi! I thought I'd write this up while it was fresh in my mind. It could be used as an alternative method to the current proposed client authentication mechanism. We could implement both, or just this, or just the other.
My description here will be a bit terser than we'd want in a proper proposal, but I wanted to share it.
This design is based on George Kadianakis's client authentication design; it won't make sense unless you've read it.
OK people,
I have a more mature torspec branch now for your eyes and only. Please see branch `prop224_client_auth_4` in my torspec repo: https://gitweb.torproject.org/user/asn/torspec.git/log/?h=prop224_client_aut...
The changes are based on the feedback and discussion on this thread.
The only real changes from `prop224_client_auth_3` is that it increases the max descriptor size to 50k, and it removes the username/password intro-level authorization.
Please let me know of anything that seems off, or anything that can make the proposal more readable. Otherwise, we should merge this upstream and move forward with fixing the already merged prop224 HSDir code.
Thanks!
Hello,
I merged the above patch to torspec.git.
Thanks for the feedback and helpful comments everyone!