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
Provide the public key in AuthenticatorAttestationResponse
#1363
Comments
While I'm still wondering if a simple HTML element (no JavaScript) would help websites even more... if you're worried about backwards compatibility, you could add a |
Actually, call the method
So everyone can easily get all of the data out of |
This is a duplicate of #557; there, the resolution was:
I agree this seems like the cleanest way forward - probably as methods or getters on |
In the interest of having something concrete to work with, I'll propose updating the
where
Analogues for |
Another thought I just had: maybe it would make sense to make the simplified API available only if the request sets |
Somehow I missed the reference to |
wrt @emlun
hm, in looking at Maybe just returning the [ Also, I suspect we would need to look closely at the various involved specs to ascertain whether the various crypto algs (and parameters thereof) WebAuthn uses (IANA-COSE-ALGS-REG) and JWK's and those that WebCrypto supports are congruent. not a big task but necessary due diligence IIUC. ] |
@equalsJeffH Yeah, my expectation is that RPs would just export the
Good point! |
Using I only selected PEM because it's already base64 encoded (easy to send to the server), and I could provide it directly to Admittedly I'm not sure if I should be trusting the PEM value like that, as it's a value that's come from the (potentially hostile) user - as in, could they provide a value that's dangerous? denial of service? I've also had a look at some of the other projects (notes below), and while most seem to work with the X and Y values directly, PEM/DER was fairly common. Notes on other projectsGo: duo-labs/webauthn; uses
Go: koesie10/webauthn; uses Java: google/webauthndemo; looks like
Java: webauthn4j/webauthn4j; stored in NodeJS: fido-alliance/webauthn-demo; uses .Net: abergs/fido2-net-lib; looks like
Python: duo-labs/py_webauthn, uses Ruby: cedarcode/webauthn-ruby, uses |
FWIW, speaking on behalf of webauthn-ruby at least, I think it is a tiny bit more accurate to say we are working with the "COSE Key format" (ref), not with X/Y directly (We switched while ago in order to support RSA keys whose params are not X/Y) by relying on cose-ruby. |
Thanks @grzuy, sorry for the guesswork - as you can probably tell, I'm not familiar with Ruby. I'm just trying to work out what the best export format(s) would be. My understanding of the "COSE Key Format" is that it's still effectively binary, so I assume you would need something like base64 encoding to get it back to your server, where it will be stored, and later used for verification (would that need a server side CBOR decoder as well?). So I'm wondering, do you think the "COSE Key Format" is the best approach for all Ruby projects? or are there better formats? Ideally it would allow the transfer (browser to server), storage, and signature verification steps to be done using as few steps/dependencies as possible. In the PHP world, I can pass the PEM encoded value directly to the server via a POST request, store it in the database, and pass it directly to OpenSSL with no extra dependencies (I'm still not sure if that's safe to do, but I will be checking that soon). |
No worries :-)
Yes. For anyone using
Yes.
So, in summary, the "flow" of the credential public key is: WebAuthn API ==> webauthn-json ==> webauthn-ruby ==> cose-ruby ==> cbor-ruby
With # After binary parsing credential_public_key_cbor out of Authenticator Data
credential_public_key = COSE::Key.deserialize(credential_public_key_cbor) I hope eventually there will be a COSE library (at least having key deserialization) for every "somewhat popular" programming language. I see just a few in https://github.com/topics/cose, as of today.
|
@grzuy, thanks for the overview. I'm just wondering if we could go a bit further, rather than every project needing to include multiple libraries/dependencies, could we get the requirements down to 0? As in, avoid any parsing, and simply have the browser provide you something that can be:
In PHP, if the browser provided the key with PEM encoding, the signature checking step can be done with the core functions provided by PHP:
So when it comes to Ruby, is there anything built in that can do the signature verification step? and if so, what format(s) does the key need to be in? |
@agl Need a PR created stating solution |
This change adds a getPublicKey method to the AuthenticatorAttestationResponse to save some users from having to parse out and handle COSE keys. (See linked issue for background.) Fixes w3c#1363
I don't see how |
For those following along, this should now be supported in Chrome Canary on both desktop and mobile. |
@agl Can you clarify what "this" refers to? There are a few things proposed in here and it's unclear which one Chrome went with. |
@MasterKale Sorry, I mean the functionality in the attached PR #1395. I.e. the |
@agl Thanks for adding these methods to the spec and Chrome Canary. The JS to create and get is considerably easier now (well, they will be when available everywhere, or I get the time to create a polyfill). The only minor annoyance is creating uint8array, and parsing array buffers, so they can be JSON friendly; but I don't think that's something that can be easily changed. As to the choice of DER Encoding, I think you're right, it's much better than PEM, as that's just adding on an extra layer, which isn't too difficult if you're using
|
For anyone interested, in the last hour I've created a very basic polyfill.js, not done much testing, only works with algorithm -7 (ECDSA with SHA256), and I've not found a way to conditionally load it. |
Anybody have a working Java code snippet on how to verify the publicKey (from AuthenticatorAttestationResponse.getPublicKey()) on the Java server side? This is what I have and it runs through but I always get isCorrect==false
PS: AuthenticatorAttestationResponse.getPublicKey() is really great! I just spent 3 days trying to CBOR decode everything in Java on the server before I found this. Any advice what I am missing in my code to verify the authenticatorData using the signature is highly appreciated! Testcase info: Google Chrome on Android + Fingerprint, platform authenticator, public-key alg -7 |
(@CrazyChris75 this issue is closed so people might not see your updates.) This line gives me pause:
|
@agl thanks for your reply! I should have mentioned that YES, I encode all JS ArrayBuffers to base64url before sending data to the Java server and the byte[] I assume the problem is somewhere in Java and my attempt to verify the signature using SHA-256, "EC" KeyFactory, X509 Encoded Key and SHA256withECDSA Signature - since I am not sure if that is at all correct. But there are so many potential points of failure in this that I could be totally wrong of course. |
There's nothing that I can see that's obviously wrong with the code above. I would check that values are what you expect by hex dumping them in Javascript, and on the server, and confirming that nothing has gotten crossed, or weirdly encoded. |
The public key for a freshly created credential is provided inside of the attestation object. However, that is a somewhat complex format that involves decoding CBOR in order to read the public key. If a site doesn't care about attestation (as many won't) we might usefully be able to have browsers provide fields of this structure more directly.
Assumption: absent attestation, web site implementations wouldn't need CBOR if we did this. This appears to be true at first glance since the authenticator data is a fixed-offset binary format (not including extensions).
A reason not to do this would be that it encourages sites to depend on these additional fields, which will only be available in newer browsers. Thus people with older browsers might not be able to use WebAuthn, even though they could if sites put in more work. However, this argument applies to any such ergonomic improvement to the API and so, if we buy it, we're forced to conclude that they're mostly a bad idea as a class.
The text was updated successfully, but these errors were encountered: