Google Smart Lock is an app for iOS and Android devices that can talk to U2F security keys over bluetooth and NFC. Wouldn’t it be great to use it with the WordPress Two Factor plugin?
Turns out the app registers a custom u2f-google
URL protocol with the iOS which can be used by any other app (including the Safari browser) to open the app with the necessary payload for the U2F authentication, which has the following format:
u2f-google://auth?data=PAYLOAD&returnUrl=RETURNURL
where PAYLOAD
is a JSON string (urlencoded twice) with the following schema:
{ "type": "u2f_sign_request", "appId": "https://www.gstatic.com/securitykey/origins.json", "challenge": "CHALLENGEFROMTHEAPP", "registeredKeys": [{ "version": "U2F_V2", "keyHandle": "UNIQUEKEYHANDLE", "transports": ["usb"] }, { "version": "U2F_V2", "keyHandle": "UNIQUEKEYHANDLE", "transports": ["ble", "usb", "nfc"] }], "timeoutSeconds": 180, "requestId": 123456789, "displayIdentifier": "NAME@EXAMPLE.COM" }
where CHALLENGEFROMTHEAPP
is a cryptographic challenge generated by the U2F client (the WordPress plugin) and registeredKeys
is a list of all the registered U2F devices with the U2F client (which must include the U2F key to be used over bluetooth).
The app now sends this data to the U2F key via bluetooth which responds with a message that gets added to the RETURNURL
as a URL hash RETURNURL#chaldt=PAYLOAD
where PAYLOAD
is again double-urlencoded and has the following format:
{ "type": "u2f_sign_response", "requestId": 123456789, "responseData": { "clientData": "CLIENTDATA", "signatureData": "SIGNATUREDATA", "keyHandle": "KEYHANDLE" } }
where responseData
contains the SignResponse
object as defined by the FIDO U2F JavaScript API. This data can now be used by the client to verify the signature and complete the authentication.
The Hack
To make the Google Smart Lock app work with the Two Factor plugin, we should adjust the u2f-google
link payload with our own data and set the correct returnUrl
.
Unfortunately, the Smart Lock app ignores all requests where the returnUrl
doesn’t start with https://accounts.google.com/signin
which is a real shame because it would allow any site to offer U2F authentication without creating a custom middleware app for talking to U2F keys over bluetooth or NFC.
Nice post! Are you sure Google Smart Lock will allow NFC to work on iOS? IFAIK, this requires an NFC write capability, which iOS does not currently allow.
Also the note here:
https://support.google.com/titansecuritykey/answer/9115487#titan_key_compatibility
says that NFC won’t work, except when Android gets an update.
You’re right! This article from Yubico mentions only reading OTP over NFC:
I have ended up implementing a functionally equivalent app to the Google Smart Lock iOS app, not in small part thanks to the info in this post :)
https://github.com/billinghamj/u2f-ble
It implements the signing part of the U2F standard in a pretty much equivalent way to Google’s, including full support for facet IDs, etc.
Probably a useful base for anyone looking to do something equivalent for their project.
This looks great, thanks for sharing James!