-
Notifications
You must be signed in to change notification settings - Fork 791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add security key support #496
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please ignore all the other review comments and the TODOs below for now.
This just encrypts the user's password directly with the credential id. The credential id isn't secure (I.e. we can't guarantee that it's random data). We can sign and verify data, but webauthn does not provide any way to securely encrypt data (it looks as if only client-server flows were considered). It seems to be possible using native code, but that would probably be too complicated from a user's perspective. I found lots of good discussion on encryption using fido keys below. It looks like our best bet would be to propose changes to the WebAuthn API...
https://groups.google.com/a/fidoalliance.org/d/topic/fido-dev/kMe6Kb4GCpU/discussion
https://bugs.chromium.org/p/chromium/issues/detail?id=1023225#c7
https://bugs.chromium.org/p/chromium/issues/detail?id=1023225#c12
https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#sctn-hmac-secret-extension
Old review comments
- WebAuthn supports linux
- check if webauthn is supported on the browser before showing the button https://caniuse.com/#search=webauthn / MDN
Can we store thesecurityTokenEncryptedKey
inkey
so that it is stored in backups? How will backups work with this in general
@@ -353,5 +353,20 @@ | |||
}, | |||
"algorithm": { | |||
"message": "Algorithm" | |||
}, | |||
"operationFailed": { | |||
"message": "Operation failed." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Crowdin is going to flood my email again :(
use updateFailure
"message": "Operation failed." | ||
}, | ||
"noPassphraseWarning": { | ||
"message": "You must set a passphrase before enable security key." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"message": "You must set a passphrase before enable security key." | |
"message": "You must set a password before adding a security key." |
"message": "You must set a passphrase before enable security key." | ||
}, | ||
"securityKeyEnabled": { | ||
"message": "Security key enabled." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"message": "Security key enabled." | |
"message": "Security key added." |
@@ -29,12 +40,31 @@ export default Vue.extend({ | |||
computed: { | |||
wrongPassword() { | |||
return this.$store.state.accounts.wrongPassword; | |||
}, | |||
securityKeyEnabled() { | |||
return !!localStorage.securityTokenEncryptedKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!!
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!!localStorage.securityTokenEncryptedKey
always has bool value
"message": "Security key enabled." | ||
}, | ||
"alreadyEnabledSecurityKeyWarning": { | ||
"message": "You have already enabled security key, do you want to continue?" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"message": "You have already enabled security key, do you want to continue?" | |
"message": "Your old security key will not work, are you sure you want to continue?" |
user: { | ||
name: "Authenticator", | ||
displayName: "Authenticator", | ||
id: new Uint8Array(16) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really ok for us to just have blank ids?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it will be some random chars without setting a value just like C language. I will update to use a random string.
displayName: "Authenticator", | ||
id: new Uint8Array(16) | ||
}, | ||
challenge: new Uint8Array(16), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should have some random data. we should verify that the key is working and response is signed properly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't care about the credential, we are only intereted in credential id
{ type: "public-key", alg: -7 }, | ||
{ type: "public-key", alg: -35 }, | ||
{ type: "public-key", alg: -36 }, | ||
{ type: "public-key", alg: -257 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is deprecated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the only supported algorithm for Windows Hello. https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/windows-integration/web-authentication
{ type: "public-key", alg: -35 }, | ||
{ type: "public-key", alg: -36 }, | ||
{ type: "public-key", alg: -257 }, | ||
{ type: "public-key", alg: -258 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not recommended
{ type: "public-key", alg: -36 }, | ||
{ type: "public-key", alg: -257 }, | ||
{ type: "public-key", alg: -258 }, | ||
{ type: "public-key", alg: -259 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not recommended
There is already a draft: w3c/webauthn#1424 |
Correct. Credential id is generated with the hardware, and it's value can be gotten only when the user touch the figure scanner or type the PIN. Though WebAuthn doesn't provide a way to encrypt data, but we also never expose the credential id, so I don't think there is a risk.
No, we shouldn't touch native code. It's beyond our scope. And we can't maintain native code for all platforms. |
Unfortunately, this is not the case. There is nothing preventing a vendor from making the id a hash of publicly known information or a serial that is incremented every time a new credential is generated. In either case an attacker would be able to get plaintext user password with current implementation. The below email thread is a good example of a security key vendor about to do that. It's worth noting that the Yubico dev says that it's completely up to the vendor how this is implemented. https://groups.google.com/a/fidoalliance.org/d/topic/fido-dev/5mwvgna3RKc/discussion Below is a link to the spec, the "key handle" is the rawId. Same as above, there is nothing explicitly preventing an easily guessable id.
As I understand it, normally you are supposed to store the credential id somewhere and use it when calling credentials.get. Without storing the id, there is no guarantee that we will get the same credential if the user ever regenerates their key. I recently found that some browsers already have an hmacCreateSecret extension we could use to do this in a secure way. It seems that it was made specifically for Windows Hello support. What do you think about using that? https://groups.google.com/a/fidoalliance.org/d/topic/fido-dev/SX6AoLAoOx8/discussion |
There isn't a standard for how to generate credential id hash, so the attacker also has no idea how to generate the credential id with RP id. Also, user id is a random number that only use once when we register the device. We don't store user id, either. The way we use webauthn here is very different from how it is designed. We don't store anything but the encrypted secret with the credential id. The only thing can be known without customer's permission is RP id.
The way we use webauthn here is very different from how it is designed, we don't store the credential id. The credential id is stored in the hardware security chip. Instead of using I understand webauthn is not designed for encryption. However, if the credential id cannot be read without customer's permission, it can be a good key to protect the data. |
I have thought about this for the past few days, and I am still not comfortable with this. I do not think that using a standard in a non-intended way is a smart move when dealing with sensitive user data. We do not have any guarantees nor can we make any assumptions about the entropy of the key handle. If you still want to move forward with this and keep the same encryption scheme, we should send an email to the fido-dev mailing list and get an opinion from the implementors and developers of the spec. |
I totally agree with you.
We have no need to move forward in such a hurry. This is not an urgent or required feature. I just publish it for review and discussion. Let's make everything reliable and ready before ship it. |
https://groups.google.com/a/fidoalliance.org/d/msg/fido-dev/kMe6Kb4GCpU/EZjN19qhBQAJ It seems HMAC extension is not what we want |
I missed that, I was mistaken. After re-reading that thread, it is clear that we should not be using WebAuthn for encryption at all. |
Correct. We have to wait for new web standard for data encryption scenario. I'm closing this PR, and keep an eye on the change in W3C org. |
No description provided.