
Two-factor auth with public-key cryptography - kenforthewin
https://www.kenforthewin.com/two-factor-auth-with-public-key-cryptography/
======
amingilani
I applaud your creativity Ken! However, this concept has been explored before,
and in fact, you could think of U2F tokens as devices with private keys.

We've already gone through a number of solutions, and regardless of the tech
you built, this is just another example of an app-approval flow. Twitter &
Facebook allow you to approve logins from already approved apps, and while
their underlying tech is different from yours — your server can still change
the tech maliciously.

For a brilliant app idea, see Kryptonite[1]. It lets you install a browser
add-on that pretends to be a U2F key, but the private keys are stored in your
phone's secure key storage (Keystore for Android & Secure Enclave for iOS).
The experience is similar to what I assume your approval from a phone would
be, but it works on all website that support U2F.

For your own site, I'd recommend using U2F tokens and TOTP + OTP keys, they're
considered really good solutions, and while SMS is considered bad — it's still
better than no 2FA. Please see the post by Troy Hunt[0] on 2FA from late last
year. It covers more than I possibly could.

Sorry for the negative critique, but I'm sure you'll build something great
next time ;) Instagram was first launched as a Foursquare clone[3]

[0]: [https://www.troyhunt.com/beyond-passwords-2fa-u2f-and-
google...](https://www.troyhunt.com/beyond-passwords-2fa-u2f-and-google-
advanced-protection/)

[1]: [https://krypt.co/](https://krypt.co/)

[3]:
[https://www.theatlantic.com/technology/archive/2014/07/insta...](https://www.theatlantic.com/technology/archive/2014/07/instagram-
used-to-be-called-brbn/373815/)

~~~
def_true_false
SMS is worse than nothing.

~~~
JoshTriplett
SMS as a _second_ factor is not a net reduction in security. The ability to
hijack a phone via number porting or similar could give access to SMS
messages, but by definition a _second_ factor should never _reduce_ your
security.

What does reduces security is the use of SMS as a password reset mechanism, or
any similar method that uses SMS as the _only_ factor for authentication.
Don't do that.

~~~
def_true_false
It gives users a false sense of security and providers an excuse not to
implement something better. Most (all?) of those who only support SMS 2FA also
get the part about no resets wrong.

------
amaccuish
This to me seems like faux security. The server can just send its own custom
key to an already authenticated device, which will gladly encrypt the main
private key and hand it back to the server which can decrypt it. Even if the
previously authenticated devices tries to directly communicate with the new
device not via the server, presumably the server could also give its own IP as
the new endpoint.

I get that security is a bunch of trade-offs, but this seems post seems to
present it as a fool-proof method, since the goal is to prevent the server
from being able to see the private key ("how can the user's private key be
transmitted in a way that doesn't reveal their credentials to the server"),
and the given solution doesn't actually fulfil this goal.

~~~
kenforthewin
In that case, the authenticated device could have the ability to show the
public key before accepting a request, and match it with the public key
generated on the new device. But yes, at some point you'll have to put trust
in the server not doing malicious things like that, which is one reason it's
open source

~~~
enedil
Sorry for blunt words, but that's bullshit. If there is no proof a client is
secure from malicious server, then this system is useless from the security
point of view. You can have open source solution, but you might be running
tweaked version.

~~~
zrm
The key is to have an open source client and a protocol that protects against
a malicious server.

One way to do this is to have the new device generate a random passphrase,
display it on the screen and require it to be typed into the already
authenticated device. Then the devices can use PAKE with that passphrase to
establish a secure channel between each other. Even if the data still goes
through the server, it's encrypted and the server can't read it.

Another method is to have the new device display its public key as a QR code
and have the existing device scan it.

------
CaliforniaKarl
If I understand right, an existing user (who already has an account, and a
device) wants to add a new device, they…

• On new device, make a key pair.

• On new device, log in to server and send new device's public key to server.

• Server sends approval request to old device, which includes the new device's
public key.

• On old device, receive the approval request and the new device's public key.
Decide to approve new device.

• On old device, take old device's _private_ key, encrypt with new device's
public key, and send encrypted blob to server.

• Server relays approval message to new device.

• New device decrypts blob, and deletes its original key-pair (that was
generated at the start). New device now uses old device's private key. The
public key is derived from the private key.

So in the end, old device and new device have the same key pair.

Please let me know if I got that wrong!

Assuming I got it right, this strikes me as problematic, because it means that
all the devices are sharing a private key. If any one device were compromised,
then all past messages would be exposed; if the compromise were to go
undetected, then future messages would also be compromised.

~~~
weitzj
I agree. You would be better off, if you have a private key per device and
increase your logic on the server side (multiple devices per user), to allow
for easier revocation of stolen devices.

“Linking multiple devices” via their public key is still fine, since the user
has to login once with email/password (or by some other means).

If you were to have the requirement of needing multiple private keys to
decrypt a message, that would be a different thing - maybe to ensure in a
group chat only the current group chat members can decrypt the messages. And
whenever a member leaves/joined a new group secret gets generated based on all
private keys of all members. But then what would be the benefit of this ?

------
paulsutter
Moving the private key seems unnecessary. Wouldn’t it be better to keep the
key locked in the secure enclave on each device, and allow multiple keys for
each user? Then devices can also be removed from the account.

~~~
snarf21
Isn't the whole point to keep the private keys in some kind of secure element
that is tamper resistant and never exposed? On iOS you can't even export
private keys generated on the secure enclave, which is exactly how I expect it
to work. There are other ways to securely transfer accounts without creating
vulnerabilities.

~~~
ptoomey3
As noted elsewhere in this thread, I’m not advocating this homegrown solution.
But, I will play devil’s advocate a bit. Yeah, sure, a Secure Enclave key per
device is more secure than not. But, what is your threat model where this is
the priority? The only realistic threat model where the enclave (or hardware
security key) would come into play is malware running on the device. But, in
that situation, you are probably hosed anyway. The malware can read browser
session cookies. Or, it can interact with the enclave or external dongle in
ways that would grant them access to whatever site they want by sending bogus
site challenge requests for site X to the enclave/dongle when you meant to
approve a challenge for site Y.

I personally think there is potentially a big security usability win by using
a securely (key part here) synced private key (via iCloud Keychain for
example).

------
privateSFacct
Interesting to see a hacker news expert coming up with something with some
good buzzwords - two factor and public-key crypto.

That said, I like the apple approach better here.

No forward secrecy? Passing private keys all over the place?

Look at how apple does it. Private keys stay on device in secure enclave, even
user cannot export from there. I don't even think system root (which user and
software generally don't have access to) can export private keys.

Adding a new device to the account involves old device generating a funny
looking wave pattern which new device scans. This has always worked fine for
me. I assume apple then adds public key of new device to my acct.

------
killjoywashere
Ken, thanks for posting, though I imagine it presently feels like you have
been nuked from orbit. Once you've digested what's been said here, please
consider either updating the blog post with a warning or, possibly, a
retraction. I suspect you will be getting some pagerank generated traffic and
it would be best for those folks to get a fair warning. Maybe even point
everyone back to this discussion, which has been fairly informative for many
people.

------
agrinman
It seems like you do not verify the public key of the new device (client-side)
before encrypting the authenticated device's private key to it?

Your server can then impersonate a "new device", generate an ephemeral key
pair, send the public key to all the user's authenticated device and perhaps
trick the user into encrypting their private key to it. One way to prevent
this is to show some sort of fingerprint on both the new device and the
authenticated device proving that the public key is the correct one.

~~~
sneak
1) According to experiments, users associate the term "fingerprint" with
crime, not security.

2) Users, even ones who know what fingerprints are and care, do not validate
fingerprints. The rest of the users (the other 99.9%) don't either. This is
not a good UX.

~~~
agrinman
I don't know about 1 but definitely agree with you on 2.

You could make validation part of the workflow (before you can even "say yes",
you need to scan a QR code for example). You might say this is also not good
UX and I wouldn't disagree. Cryptography + good UX is a hard problem.

------
rfugger
Not really 2FA, just private key transfer to another device.

~~~
deathanatos
…which forms the second factor, the "something you have". (The private key.)

I don't really see how it's very different from an external security token
that does basically the same thing. (Though an external security device can
make it _very_ difficult for something malicious to get at the private key,
which is good.)

------
nmadden
Firstly, this is just authenticating the same factor over a different channel.
(Actually the exact same credential). So not 2FA.

Secondly, if I can successfully get you to approve my login request then I not
only get logged in but also receive a copy of your private key? That is a
really bad failure mode.

------
sneak
Doesn’t this design for users that have multiple devices? Don’t most users
have a single phone at a time?

~~~
kiallmacinnes
Sure.. but Phone, Tablet, Laptop, Desktop, Office Desktop, etc. I want my chat
apps to work on all, be sync'd on all, and be secure.

(Though I'm not convinced the proposal in the article is all that secure - as
others have pointed out, it seems trivial for an evil server to obtain the
private key..)

------
welder
Mozilla tried this before with BrowserID/Persona but it didn't catch on with
website owners.

[https://en.m.wikipedia.org/wiki/Mozilla_Persona](https://en.m.wikipedia.org/wiki/Mozilla_Persona)

------
the_arun
So the new device will have user’s private key after MFA? Isn’t this a
security risk?

------
ptoomey3
This feels vaguely like a homegrown version of webauthn, but without any of
the niceties of having the browser enforcing origin protections and ensuring
the credential isn’t lost if cookies/local storage are cleared.

------
packetized
I’m curious to know what benefits accrue from sending the user’s private key
over the wire (even encrypted). It seems a strange concept, at odds with
ephemeral key usage.

~~~
zokier
It helps to keep the whole crypto system simple and understandable.

~~~
packetized
Arguably, private keys should not ever leave the device on which they were
generated.

------
dfialho
What happens if a user is authenticated in a single device and that device
breaks? Is there a way for the user to authenticate with another device then?

------
dfialho
What happens if the user is authenticated only on its phone and that phone
breaks? How can that person authenticate a new device then?

------
onemantaker
Probably everyone is doing it. What's new in yours ?

