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
WIP: Implement U2F TwoFactor Authorization (on Android) #662
Conversation
src/Android/MainActivity.cs
Outdated
private async Task<bool> ListenU2F(Dictionary<string, object> data) | ||
{ | ||
var appId = Uri.Parse((string)data["appId"]); | ||
var challenge = Encoding.ASCII.GetBytes((string) data["challenge"]); |
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 believe that challenge is a "url safe" base 64 encoded string. See here for a method that can decode that: https://github.com/bitwarden/mobile/blob/master/src/Core/Services/TokenService.cs#L203
Might want to mvoe that method into a static core helper.
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.
Thanks for the hint, will try that in the next few days.
I'll clean that up once I got everything up and running. I just noticed that I'll need at least 2 entrypoints to the U2F functionality when I started and before that I just picked up where you left comments about implementing U2F sometime in the future.
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.
Do you by any chance know how the U2F appId must be formatted? I fear that this is my actual problem here. The Bitwarden Server returns a link to the https://vault.bitwarden.com/app-id.json and from the documentation of U2F I read, that's not a valid app identifier. Instead it seems like this just tells me which appIds will be accepted by the server when I open that reference.
I think I might need to insert the Android App ID in the appId field, but I'm not sure how to obtain that yet.
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.
The app id should be https://vault.bitwarden.com/app-id.json
.
If that doesn't work, then maybe try android:apk-key-hash:dUGFzUzf3lmHSLBDBIv+WaFyZMI
, which is defined in that JSON file for the Bitwarden android app.
src/Android/MainActivity.cs
Outdated
foreach (var key in keys) | ||
{ | ||
var keyHandle = new KeyHandle( | ||
Encoding.ASCII.GetBytes(key["keyHandle"]), |
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.
Might be the same, a "url safe" base 64 encoded string
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.
any updates?
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.
No, I haven't found any documentation on how the Original Android API is supposed to work with other providers than Google itself. There's also no Open Source projects using either the Xamarin Library or the original Android Java classes to access third-party U2F/FIDO2 providers. I'm pretty much stuck not knowing what I might do wrong/what format the Android API expects.
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 am not really in this topic, but why https://github.com/android/security-samples/tree/master/Fido not helps / is not an option?
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.
Sadly that sample only covers how to get the authorization request from Google / for the Google account stored in the phone. The example doesn't show how to create that request because the Android API for the Google Account provides a ready-made object. It appears like noone has ever used the native U2F/FIDO APIs except for the Google account. There's lots of examples how to use U2F in the browser, even on mobile, but there's nothing about the native Android API.😟
Benedikt Bauer, M.Eng.
On Fri, Feb 21, 2020 at 6:44 PM +0100, "Nerrix" <notifications@github.com> wrote:
@nerrixde commented on this pull request.
In src/Android/MainActivity.cs:
@@ -278,6 +297,40 @@ private void ListenYubiKey(bool listen)
}
}
+ private async Task<bool> ListenU2F(Dictionary<string, object> data)
+ {
+ var appId = Uri.Parse((string)data["appId"]);
+ var challenge = Encoding.ASCII.GetBytes((string) data["challenge"]);
+ var keys = ((JArray) data["keys"]).ToObject<List<Dictionary<string, string>>>();
+ var registeredKeys = new List<RegisteredKey>();
+ foreach (var key in keys)
+ {
+ var keyHandle = new KeyHandle(
+ Encoding.ASCII.GetBytes(key["keyHandle"]),
I am not really in this topic, but why doesn't https://github.com/android/security-samples/tree/master/Fido helps / is an option?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
|
@mastacheata 1Password recently released their Android app (version 7.4) with security key support. It looks like they've found any solution. |
1password isn't open source and most likely not written in Xamarin. |
Not having U2F support on android is a major issue for me and makes me really consider switching to 1password away from Bitwarden. |
I'm fine with the biometric authentication on my phone, but would definitely like to have U2F/FIDO2 as well, but I'm a web developer by trade and have close to zero knowledge of mobile development. Pretty much all the documentation you can find on both U2F and FIDO2 are strongly linked to Web Authentication through the browser. On Android you can easily get both to work in Chrome and Firefox and it even works on iOS if you use the Brave browser (no idea how they managed to include that feature as it's just like all other browsers only a wrapper around the included Safari on iOS). If you find any documentation/examples about how to do FIDO2/U2F/Webauthn on Android in a native application and NOT using the Google account, please let me know and I'll try to pick up my work on this feature again. Otherwise, we'll have to wait and see if Kyle (the author/lead developer of Bitwarden) can find some time to look into that or find someone with more knowledge... |
For all waiting: 1password currently supports 2FA on android. |
mKonrad already noticed that 3 posts above. |
@Bitwarden-Staff How is the priority? You really should prioritize it, as consumers want it. Some consider switching. |
I have not dug into the code, so I have absolutely no idea if this would prove helpful, but the OnlyKey guys have done some work with communicating with their usb token over U2F on android. |
Is it really important for it to be U2f? FIDO2 is backwards-compatible wit U2F and the android APIs for FIDO2 Closely model the welldocumented However this might require changes on bitwarden server. Is that realistic? |
@mastacheata was this in the emulator by any chance? I have the same issue when trying out the FIDO2 API using Google's own examples. I think FIDO2 stuff in the emulator is just bugged |
Sadly, no. This was debugging on a physical device. (Pixel 3 and HTC10) Maybe it's an option to ditch the native approach and instead use a WebView? Both Chrome and Firefox (only the stable version, not the Preview yet) work perfectly fine with WebAuthn / FIDO2 / FIDO-U2F.
That's optional and up to the server to decide that.
There are by far more U2F tokens than there are FIDO2 ones around. (At least if you exclude the Android software-token where your device can act as security token for your PC or another phone) Whether you do that via the Webauthn/FIDO2 API or the U2F API doesn't matter, I think. |
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.
any updates?
Any update on this? This would be a major feature that would help convert a few to Bitwarden Premium |
Updates? Is there still the same issue with this? |
Yeah, I haven't done any work on this as you can see and only opened this PR to look for support from other developers. Sadly Bitwarden doesn't seem to attract many developers and is pretty much developed solely by the company itself. In the Bitwarden forum one of their devs announced U2F being pretty high on their roadmap. That's it however. No news or timeframe after that. |
That's unfortunate then. It'd be interesting to have a crack at it, still. Some time has passed maybe it'd be more clear how to implement FIDO U2F now than back when you did it. EDIT: okay. So the development is ongoing but nothing else is known. Alright... that's quite demotivating. Guess we'll just have to wait |
NOTE: This is a work in progress, just opened the pull request in order to properly share the idea and ask for help,
I started working on FIDO-U2F 2nd Factor stuff yesterday, but only got to a point where it will immediately return from the intent without even trying to ask for a token. Instead I get an ErrorResponse with ERROR_OTHER as the Response Code.
I've so far identified 2 possible causes, but am not sure about that as there is no more information in the error than "Other".
Cause 1 woud be that I have the appId wrong. I tried to get that from the challenge issued by the Bitwarden server, but that might be a mistake as a JSON URL is not actually an appId. Instead I should probably pick one of the IDs from that JSON file (in this case, the Android App identifier).
If that is the case, should I just hardcode the ID, grab the one from the remote JSON or is there a way for the Android part of the app to know it's own ID?
The other thing that might be wrong is how I deserialize and then convert to the requested byte array for the keys from a string. In the debugger the string representation of the keys list changes multiple times between the string from the JSON response, the byte array and the "RegisteredKeys" object.
In the end I somehow need to retry the login with the signed challenge / the response from the U2F key. I have no idea how to do that, All the other 2-factor challenges work without sending a challenge to the 3rd party and are either time or account based as it seems.
I guess I'll figure that out as soon as I got the correct signed challenge / the response from the U2F token.