Closed cuu508 closed 2 years ago
Ah, OK, assuming on the server I have
legacy_credential = {
"appId": "https://localhost:8000",
"version": "U2F_V2",
"keyHandle": "AbC0GNAXtomrBtRKWSB7ajFN4MvMvr4-JzN4B1fBYLb0CYKWczWfwwpse3pn-WLxEtWy7CzBH99msfN5UXX0JA",
"publicKey": "BDHXJn4OpNR1vLpcGWL1QLPMv1xfKpmuGJw6FsuovpvrYpztIFENLWdvMYot0J9m3bzrzIzqbwxR1BmgCsUH7BU",
"transports": ["usb"]
}
looks like I can do
raw_keyhandle = base64.urlsafe_b64decode(legacy_credential["keyHandle"] + "==")
credential = PublicKeyCredentialDescriptor("public-key", raw_keyhandle)
options, state = server.authenticate_begin([credential])
Alternatively, thanks to fido2.server._wrap_credentials
, this also works:
raw_keyhandle = base64.urlsafe_b64decode(legacy_credential["keyHandle"] + "==")
credential = {"type": "public-key", "id": raw_keyhandle}
options, state = server.authenticate_begin([credential])
It's important to use base64.urlsafe_b64decode
instead of base64.b64decode
because they decode -
, _
, +
and /
differently.
Turns out authenticate_complete
only accepts credentials as AttestedCredentialData
instances.
After some code diving, here's how I managed to create an AttestedCredentialData
instance from legacy U2F registration data:
from fido2.ctap2.base import AttestedCredentialData
from fido2.utils import websafe_decode
key_handle = websafe_decode(legacy_credential["keyHandle"])
public_key = websafe_decode(legacy_credential["publicKey"])
credential = AttestedCredentialData.from_ctap1(key_handle, public_key)
(sorry – this is not an issue, more a question on how to use the libary)
I'm looking at migrating a webapp from U2F to WebAuthn, and want to make sure the existing, registered U2F keys keep working. The registered keys are stored on the server side like so:
How do I instantiate AttestedCredentialData (or PublicKeyCredentialDescriptor?) from this, for passing into
U2FFido2Server.authenticate_begin()
?Thanks in advance for any tips!