Skip to content
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

Can the private keys be used for other cryptographic operations? #1595

Closed
ghost opened this issue Apr 8, 2021 · 44 comments
Closed

Can the private keys be used for other cryptographic operations? #1595

ghost opened this issue Apr 8, 2021 · 44 comments
Assignees
Milestone

Comments

@ghost
Copy link

ghost commented Apr 8, 2021

For example, can they be used to sign and encrypt data the client passes?

This goes beyond authentication, so it may be fair to consider it out of scope, given that "authn" is in the spec name! But I think being able to use the private keys more generally would open up very compelling functionality. For example, a web app could act like a mobile app in the sense that it could leverage device biometrics and secure mobile hardware to create, store, and use private keys.

This would be a major advance, since currently many uses of public key crypto that are theoretically compelling are practically infeasible because they require businesses to make users install mobile apps. Web apps are so much more usable because they don't need to be installed.

I looked all over the place to try to sort this out and didn't find anything, but maybe I'm just missing it. I thought maybe the WebAuthn extensions could fit this scenario? But I'm really not sure. There are many subtleties, like some key types not being suitable for encryption, etc.

@MasterKale
Copy link
Contributor

Correct me if I'm wrong, but isn't this a usecase for the largeBlob extension?

https://w3c.github.io/webauthn/#sctn-large-blob-extension

...allows a Relying Party to store opaque data associated with a credential...

@ghost
Copy link
Author

ghost commented Apr 8, 2021

I thought that might be true, but when I read the details of largeBlob it seems tailored to adding a (relatively small) amount of data at registration to be stored in the authenticator. The use case in mind seems to be certificates.

What I'm hoping for is the ability to use the private keys for more (ideally all possible) cryptographic operations that key can be used for. Mobile apps can do this through the OS, e.g. an iOS app can trigger a Face ID check and then pass a bunch of data to the Secure Enclave to be signed, encrypt that data (with another key tied to the Secure Enclave, though not stored there because of technical subtleties), and receive the result back. It can also receive data encrypted with the public key and use the private key decryupt it. That sort of thing.

It's always seemed odd to me that web apps can't do this also, but it's because they don't expose access to key pair generation and usage the way mobile OSs do for mobile apps. WebAuthn seems like a partial step in this direction but maybe not a full step, unless there actually is a way to use the keys more generally.

@ve7jtb
Copy link
Contributor

ve7jtb commented Apr 8, 2021

You can indirectly sign things bypassing something in as part of the challenge.

Given the primary use of the key is for authentication allowing the same key to be used to sign arbitrary data would allow a possible man-in-the-middle attacks if not carefully thought through.

We tried to add a KDF extension to WebAuthn in level 2 but there were questions about if that fell inside the working group's charter as that only mentioned authentication.

That may come back after our new charter as part of level 3.

We did add however add credBlob so a RP could store a 32byte value with a discoverable credential. That could be used to derive a key for signing or encrypting in the browser or RP.

@ghost
Copy link
Author

ghost commented Apr 8, 2021

Thanks @ve7jtb. Agreed that this does seem a bit fraught, would need to be done carefully as it's not the intended use case.

It seems that WebAuthn, WebCrypto, and similar specs are circling around the bigger topic of opening up cryptography using secure device hardware to web apps. I'm not sure why this has been commonplace for mobile apps for years but still isn't an option for web apps. It may not be possible to expand the scope of WebAuthn to include this, given how tightly coupled it is to the authentication use case, but I'm encouraged that level 3 might reintroduce broader usage of keys.

To me at least, it seems like a very natural and useful generalization. Perhaps another spec that encapsulates WebAuthn as one part.

@Firstyear
Copy link
Contributor

Given that there is a desire for this functionality, and that it can be risky if done incorrectly, it would be better for us to describe a process to do it correctly and securely, rather than relying on people to "have a guess" at it and misusing the assertion process.

@ghost
Copy link
Author

ghost commented Apr 9, 2021

@Firstyear 100% agree. I would much rather follow a community vetted process than try to shoehorn WebAuthn into a solution it wasn't designed for. I do think it may be difficult, though, to expand the spec given how tightly coupled WebAuthn is to authentication, even in name.

How can we amplify this proposal for wider consideration?

From a security perspective, there are very compelling reasons to open up secure device hardware to web apps. For anyone who's interested, I'd suggest checking out this Pomcor blog post and presentation. As they say, "Use of cryptography in web apps has been hindered by the problem of where to store cryptographic keys." Without access to secure device hardware (that's more general than the auth-only approach of WebAuthn), the only options are fundamentally insecure. How tragic! Imagine how much more powerful the web would be if hardware backed cryptography were available to web apps, especially with the rise of web 3 decentralized systems.

Anyway, now I'm just advocating ;) but would love fellow advocates to help push the cause forward!

@equalsJeffH
Copy link
Contributor

equalsJeffH commented Apr 9, 2021

From a security perspective, there are very compelling reasons to open up secure device hardware to web apps. ... "Use of cryptography in web apps has been hindered by the problem of where to store cryptographic keys."

Yes, this is a long-recognized but apparently really-tough-to-address problem. The more general Web Crypto API is likely what you want for your use cases, rather than WebAuthn, although layering WebCrypto on top of hardware-based crypto+storage facilities is presently not standardized.

FYI/FWIW, there is an existing, relevant, tho apparently dormant, Hardware-backed Security Services Community Group, whose unfinished draft report takes a stab at a WebCrypto-linked Secure Credential Storage API.

update 21-Apr-2021: see also #1595 (comment) below regarding the proposed PRF webauthn extension.

@rlin1
Copy link
Contributor

rlin1 commented Apr 10, 2021

Allowing a PublicKeyCredential private key to sign arbitrary data structures has an impact on the security model.
It makes keys "unrestricted", see https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-metadata-statement-v2.0-id-20180227.html#dictionary-metadatastatement-members

@Firstyear
Copy link
Contributor

@rlin1 That's fine, but I think that the standard needs to not only express what it can do, but also advise on what it can not and make constructive links to things like the webcrypto api or others that are able to solve this problem. IE in the section about assertion it should clearly state that the nonce should not be used to sign arbitrary data, should reference the links you provide, and give reasons.

@nuno0529
Copy link

From FIDO Security Requirement spec, at least it does not limit the private keys' usage for FIDO message only on L1/L2 levels authenticator, link.
But by the metadata spec link from @rlin1, it's FIDO server's call to support this kind of authenticator or not.

@ghost
Copy link
Author

ghost commented Apr 12, 2021

FYI/FWIW, there is an existing, relevant, tho apparently dormant, Hardware-backed Security Services Community Group, whose unfinished draft report takes a stab at a WebCrypto-linked Secure Credential Storage API.

@equalsJeffH Yes, thanks for highlighting this here. I also stumbled across this dormant group and spec draft. This spec and another one I found have just an author or two — unfortunately seems that they never went anywhere.

@rlin1 Interesting about the isKeyRestricted property. The fact that this is an option maybe suggests the spec authors wanted to leave open use cases beyond authentication? @Firstyear Perhaps using one restricted key for authentication only and another unrestricted key for other cryptographic operations would address part of your concern. Unfortunately, WebCrypto isn't really a comparable solution. It does enable more general cryptography but not tied to the device hardware, which makes it vulnerable to malware, physical takeover, etc.

@nuno0529 Are you saying that because the metadata can be arbitrary, signing data for purposes other than simple authentication is allowed by the spec?

@serianox
Copy link

@certainlyNotHeisenberg Allowing a cryptographic key for several use/algorithms is a _bad idea_™ and has led to various _catastrophic failures_™ through unexpected protocol/algorithms interactions. As an example, this is why in both PGP and X.509 certification, signature, and authentication are three separate usages for keys.

In addition to all the specifications previously mentioned, there's also Web API For Accessing Secure Element that was intended for your use case, but ultimately wasn't kept by w3c due to the lack of interest at the time.

@ghost
Copy link
Author

ghost commented Apr 15, 2021

@serianox Yes, I totally agree and know what you're getting at. But I didn't mean that a single key would be used for multiple functions. Each key could be used for only a single function, and the algorithm could be chosen specifically for that function.

So, for example, one key could be used for authentication á la WebAuthn, and a separate one could be used for signing data. Maybe these two keys could be directly connected somehow, but they'd be at least indirectly connected by virtue of being stored in the secure hardware of the same device, only accessible to a user passing through the platform authenticator of that device (e.g. Face ID on an iPhone).

The goal I have in mind is enabling the same sort of hardware backed crypto for web apps that mobile apps already have. And that seems very doable if web apps have similar access through the browser that mobile apps have through the OS. It just hasn't been done yet.

Thanks for linking to this — I hadn't come across this one. Too bad that it went dormant!

@agl
Copy link
Contributor

agl commented Apr 21, 2021

From the call of 2021-04-21:

The PRF extension, if approved and implemented, would allow a secret key to result from a WebAuthn operation. That key could be used with WebCrypto to encrypt/authenticate external data at will. The WG is interested if there are any similar use cases that would not be satisfied by the PRF extension.

@Firstyear
Copy link
Contributor

@agl This likely could work, but I think that the PRF extension text is very unclear about what it is doing. I think it needs to be clarified significantly as to what it's actually achieving.

@ghost
Copy link
Author

ghost commented Apr 26, 2021

@agl Great news, thanks for your work in pushing this forward. I do agree with @Firstyear that it's a bit confusing at the moment what the extension does in detail — even the name took me a bit to grok. This may just be due to my current lack of familiarity though.

To your question about use cases not covered... one thing comes to mind that may or may not be relevant. It's in the spirit of enabling web apps to do what mobile apps can do (in terms of hardware backed crypto). Mobile apps can perform ECDH key exchange and can call specific functions for that purpose. For example, in the iOS documentation see here and here. My sense is that this would be possible to do by bulding on the PRF extension, but I mention it in case not. Even if possible, perhaps it would be significantly easier with a dedicated function as in the mobile case?

In general, it would probably help adoption if the interfaces for mobile and web apps using hardware backed crypto were as similar as possible, both in terms of functionality and terminology. But perhaps that's stretching too far from the current specs.

@Firstyear
Copy link
Contributor

@agl Great news, thanks for your work in pushing this forward. I do agree with @Firstyear that it's a bit confusing at the moment what the extension does in detail — even the name took me a bit to grok. This may just be due to my current lack of familiarity though.

No, it's not lack of familiarity. This text should be direct, clear, and accessible so that it can be easily understood by implementors and consumers of this standard. I think it needs clarity and language improvement :) Without this it's easy for people to misunderstand it's usage and function and may lead to implementation errors.

@emlun
Copy link
Member

emlun commented Apr 27, 2021

@certainlyNotHeisenberg ECDH is essentially a pseudo-random function from the perspective of either participant (assuming a fixed key for the other party, you pass some input and receive a random-looking value determined by the input), so I think this should cover anything you could do with ECDH where you control only one of the keys.

@Firstyear
Copy link
Contributor

@emlun The problem with the current PRF spec is it's not clear what it does. Is it ECDH? HMAC? ECDSA signature? Or just a random number generator?

@emlun
Copy link
Member

emlun commented Apr 28, 2021

@Firstyear I replied to your review comments in #1424 (the PRF extension pull request), let's continue that discussion there.

@ve7jtb
Copy link
Contributor

ve7jtb commented Apr 28, 2021

It is key derivation. Based on a nonce as input you get back a key that you can use to directly encrypt/decrypt with or derive other keys from.

The goal of this extension is not really to allow non-repudiation of signatures if that is what you are after.

It will however allow applications to encrypt data at rest without needing the user to input a password to be used as part of the key derivation. This might be useful for password managers or other cloud services that don't want to be able to decrypt user information without the user being present.

I think this is separate from general-purpose hardware-backed key storage.

While WebAuthn is great and all that. I would rather see browsers support something like openPGP card as a backend for webCrypto, if you want hardware-backed signing and encryption.
That is already implemented on a lot of the current Fido roaming authenticators and could easily be added to any unlocked javacard device via open source.

Managing a smart card would need to be simplified from what is currently in openPGP card but the API is probably a much closer fit than CTAP for general crypto operations.

@ghost
Copy link
Author

ghost commented Apr 29, 2021

Thanks @ve7jtb. So it sounds like this does not provide a way to use a private key stored in device hardware to sign data passed in? @agl I think you suggested the opposite though?

@ve7jtb
Copy link
Contributor

ve7jtb commented Apr 29, 2021

This provides a way to use a key stored in the device hardware to generate a new key value based on a value (seed) passed in as an extension on the getAssertion request.

It would be up to the application to turn that value into one or more public key pairs using a KDF function using the keys output as the "PRF" input to the KDF. That is where the PRF name comes from I assumed.
https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf

So you can get symmetric or asymmetric keys for the application, but there is no attestation or proof any key is tied to a particular credential. It however provides a secure way to store the seed for generating multiple symmetric keys if you are doing symmetric encryption in an app or on a server.

So the PRF extension is probably a better fit for encryption rather than signing.

I think what you are looking for signing is more of a HSM or openPGP card backend that can be used to provide cross-domain signatures.

@Firstyear
Copy link
Contributor

@ve7jtb I don't think this is correct. It's actually based on ctap HMAC and it's for signing arbitrary data?

@emlun
Copy link
Member

emlun commented Apr 30, 2021

It is constructed on top the hmac-secret CTAP extension, yes, but that doesn't mean it's a message authentication algorithm. hmac-secret "is used by the platform to retrieve a symmetric secret from the authenticator", and the PRF extension in turn uses that to construct pseudo-random functions on top of it. See also for example HKDF, which similarly constructs a key derivation/expansion algorithm on top of HMAC.

@cybercent
Copy link

cybercent commented Apr 30, 2021

Hi, I found this discussion while searching for a way to use my Yubico key to sign data.
I'm interested in the same thing mentioned by @certainlyNotHeisenberg .
I'm building a web3 app and I want to allow people to sign data with a private key found inside their Yubico physical key.
I don't want to get the private key out, or get a seed to generate another private key, I don't want to store private keys.
We only need one feature: "sign this data with the private key associated with this public key".

Passing the data I need signed in the challenge does not do the trick as the device adds its own data before signing.

@agl
Copy link
Contributor

agl commented Apr 30, 2021

We only need one feature: "sign this data with the private key associated with this public key".

If you need to control the whole signed message then WebAuthn doesn't support that, I'm afraid. However, you can put a hash of any data to be signed in the challenge passed to WebAuthn, which effetively signs the data. The downside is that verifiers need to understand the WebAuthn signed-data format.

@cybercent
Copy link

@agl thanks, verifiers are blockchain nodes, they do no understand Webauthn, but they do understand ECC P-256. secp256k1 etc.

@agl
Copy link
Contributor

agl commented Apr 30, 2021

Probably the WebAuthn signed-message format could be expressed in Ethereum script for validation? :) (I actually have no idea if that's true.)

@cybercent
Copy link

cybercent commented Apr 30, 2021

Accounts are stored on the blockchain, it's the new web. If you want to get rid of passwords make that feature possible.
Storing data in a db is the old way of doing things, not going away soon but your Webauthn usecase is meant for that - the backend needs to store some id etc, while the reality is the backend is the blockchain, so it won't store any ids (data needs to be signed to be stored). The client connects to an account on chain that has an associated public key (was added there when the account was created), it reads the key, creates a small program (used to mutate the state of data on chain) and asks the physical key to sign the program data with the private key. The end. No passwords.

@cybercent
Copy link

@agl for data to be stored on-chain (Ethereum, or hundreds of others) it needs to be signed, so we are back to the initial problem, signing the data.

@cybercent
Copy link

Also, kind of weird that your group is working on web auth while there are no blockchain people in here.

@Firstyear
Copy link
Contributor

It is constructed on top the hmac-secret CTAP extension, yes, but that doesn't mean it's a message authentication algorithm. hmac-secret "is used by the platform to retrieve a symmetric secret from the authenticator", and the PRF extension in turn uses that to construct pseudo-random functions on top of it. See also for example HKDF, which similarly constructs a key derivation/expansion algorithm on top of HMAC.

Cool, so as discussed on the other thread, this would need to be renamed to "Key Derivation Function" then :)

Regardless, I think we should consider an extension for allowing data signatures to be produced at this point since I think that's what's required here.

@ghost
Copy link
Author

ghost commented May 1, 2021

@cybercent I feel you, but I think the people who've been working so hard to develop and get adoption of the WebAuthn spec deserve a ton of credit. It's a real step forward (and hard to push through). I'm new to this community and super appreciative of all the work that's been done.

I very much agree with you though. WebAuthn doesn't meet the needs of Web3 systems. What's really needed to make Web3 take off is generic hardware backed crypto through the browser, whether using external keys like you said or internal device hardware. (I'd argue internal device hardware is actually much more important for widespread adoption.) Imagine if we had that. Any dApp would be usable natively in standard web browsers — no MetaMask or other subpar solutions required. And lay users wouldn't have to deal with complicated crypto or managing private keys. It'd all be abstracted behind simple device biometrics.

I'm not sure it's possible at this point to expand the WebAuthn spec to accommodate this more general goal, since the spec is so narrowly scoped. But the more general goal is so compelling and very much seems like the future. It may be doable to get there, if we can just add signing data functionality.

@cybercent
Copy link

cybercent commented May 1, 2021

@certainlyNotHeisenberg Webauthn is already integrated into browsers - that's great. Awesome work, and nothing but my full appreciation on this.

Big Corp, has no way to push this tech to their users, too much friction to force a user to get a hardware key, so they only use this as an alternative to OTP (authenticator apps). Adoption is low, why compromise UX (and 20 year old habits) over slightly better security, people also do not see the advantage of replacing a free Google Authenticator app with a paid hardware key.

My point, there is a new wave of blockchain apps that NEED the security this thing was designed for. It's the missing piece.
People need to be free of passwords, magic link emails and OTP codes.
Email transitioned from a way to say "How are you Joe" to being a "Vault". Imagine keeping your life savings in your letterbox.
Developers need to be free of being in charge of their user's security. I don't want to be a custodian, but I'm forced to.
Blockchain is the new web, you should design for the future.

@Firstyear
Copy link
Contributor

Blockchain is the new web, you should design for the future.

It would be good to keep this on topic, and discuss here the exact set of cryptographic operations we want to expose in this system.

If you have blockchain related designs, they should be in seperate issues.

@akshayku
Copy link
Contributor

akshayku commented May 2, 2021

We should refrain away from ideological and philosophical debates. This WebAuthn spec was meant for authentication. We are working hard to have a stronger user verifying 2FA capable phishing resistant authentication. And webauthn signature (not raw signature) is important part of above promise.

There are other specs which deal with general purpose cryptography operations, namely WebCrypto. However, that spec does not support a cross-platform hardware keys IIUC. And it is not supported across platforms with a user verifying ability.

It is natural for have newer use cases. And I would like people on this thread to be crisp about that use case. That will help move things along.

I see two new general patterns. A desire to encrypt things. And a desire to have raw signatures.

For encrypting things, we have hmac-secret/PRF extension. That seems ok to me unless someone can tell me that their use cases cannot be solved by these extensions.

For raw signatures, couple of approaches comes to my mind.

  • During Create(), designate the key to be created to allow raw signatures and those keys are not used for authentication.
    • I am not in favor of changing existing webauthn authentication keys to also have the ability for raw signature, hence at credential creation time, RP has to specify what they want.
    • One issue with this approach is RP does not get additional benefits of webauthn signature like the guarantee around whether user was verified or not. Which may or may not be OK for an RP.
  • During Create(), we have an extension to create a secondary key for raw signature. User authenticates with primary key with usual webauthn semantics and in the extension, secondary key does raw signatures over challenge passed in the extension.

But again, I would like people on this thread to be crisp about their use case with a user journey and clear user benefit.

@cybercent
Copy link

cybercent commented May 3, 2021

@Firstyear and @akshayku thank you for your answers.

I understand the use case for Webauthn, and why device data was used in signatures.
I'm grateful for all your work in bringing this to browsers in an effort to keep everyone safe.

The requested feature would keep safe not only people that use centralized services but also people who use decentralized services.

In a decentralized service, a user registers his public key with the service and all future interactions rely on the user signing data with the matching private key.

As a user, I browse to example.com which is a decentralized application.
To use this service I need to have a public/private key pair.
Example.com gives me some choices on how to manage my private key:

  • a) generate the keys for me in the browser (promise not to steal the PK and hopefully no other extensions will), display the seed for backup purposes, and store the PK encrypted using my password in the local storage
  • b) install a browser extension that does the same thing in an iframe
  • c) install a mobile application that does the same thing, except it stores the key on the phone

When I want to authenticate to the service I need to sign some data using the PK, so I enter my password to:

  • a) decrypt private key from local storage
  • b) unlock browser extension that has the PK
  • c) unlock phone app that has the PK

The service will then sign the data needed with my PK on the client-side.

With the requested feature, the service can ask the user to sign using a security key, there are no passwords and the PK would be stored securely on the hardware key.

Edit: Regarding your propositions, I think both would work, some things that come to mind:

  • Having an extension to create a second key:
    2 public keys would be sent on create
    is there a harware key capacity issue to think of
  • Having the RP ask for a key that creates raw signatures:
    to prevent misuse the default option could be non-raw signatures

@ghost
Copy link
Author

ghost commented May 4, 2021

I opened a new issue with a full proposal, in an effort to consolidate the conversation here. See PROPOSAL: Add support for general (hardware backed) cryptographic signatures. #1608

@emlun
Copy link
Member

emlun commented May 4, 2021

I thought of an application I don't think the PRF extension covers: multi-party encryption (which seems pretty obvious in hindsight...). If the sender and recipient are the same, then a PRF can be used well enough to derive a symmetric key. But not so if the sender and recipient are not the same (and their PRFs are therefore different). For that I believe you would need direct access to some kind of Diffie-Hellman construct.

@nadalin nadalin added this to the L3-WD-01 milestone May 5, 2021
@equalsJeffH
Copy link
Contributor

Given that Issue #1608 effectively supersedes this issue, as implied above in #1595 (comment), and that the WG decided during today's meeting that we are respectfully declining issue #1608, we're also closing this issue.

@ghost
Copy link
Author

ghost commented May 7, 2021

Thanks @equalsJeffH.

For future visitors, just FYI that I posted a similar proposal to the one @equalsJeffH closed (which concerned the WebAuthn WG) for the WebCrypto WG (see here).

@earonesty
Copy link

earonesty commented Jan 27, 2023

So many protocol "standard" are fundamentally broken because the committees lack the vision to see that they cannot possibly think of all use cases.

Allowing people to shoot themselves in the foot with low level primitives is a good thing - as long as you advise them not to. (Name the function "unsafe_perform_ecdh", you're off the hook!)

You have now created a protocol that cannot support document signing, threshold signing, hardware-backed storage of cryptocurrency, and will be limited to the hashes you provide, etc.

But it could have. It would be trivial to expose some low level DH operations and let people build creative things that nobody thought of.

Then leave it up to the next standards committee for the best practices on those use cases. But instead you hamstring it, and people will be left hacking signing algorithms to create encryption functions and operating on private keys directly in javascript - just to allow someone to use their yubikey to sign a transaction or document.

And the crazy thing is that very crippled use case... is better than the status quo. So people will do it, because of these sorts of misguided decisions.

@timcappalli
Copy link
Member

@earonesty this WG has created a web platform API and protocol designed for phishing-resistant authentication on the web, as it was chartered to do.

If you feel a new web platform API and/or protocol is needed to meet your use cases, please start the process of chartering a new working group, or look at things like WebCrypto that may have these use cases in scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests