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

Specifying key ID's format #1

Open
jans23 opened this issue Aug 27, 2019 · 9 comments
Open

Specifying key ID's format #1

jans23 opened this issue Aug 27, 2019 · 9 comments

Comments

@jans23
Copy link
Member

jans23 commented Aug 27, 2019

Sign and Decrypt operations require the to-be-used key ID as a parameter. How exactly should this key ID look like? @tomholub noted, that it should be compatible to OpenPGP's long ID as specified in RFC 4880 to make it usable with OpenPGP.

@szszszsz
Copy link
Member

szszszsz commented Apr 2, 2020

The fingerprint could be calculated using the following formula RFC4880#12.2:

A V4 fingerprint is the 160-bit SHA-1 hash of the octet 0x99, followed by the two-octet packet length, followed by the entire Public-Key packet starting with the version field. The Key ID is the low-order 64 bits of the fingerprint.

This should be possible to use for both non-resident (derived) and resident keys.

Optionally, if we allow to use multiple derived keys per domain, additional integer number would be required from the JS application, so we could avoid costly searching it (by generating public key for each number), e.g. 2 additional bytes to allow 64k keys per domain.

To identify specific device having given key (e.g. in case user would have multiple ones), a device ID could be added to the full fingerprint produced by the device, which then would be parsed/stored in the JS API memory.

References:

  1. RFC4880#12.2
  2. RFC6637#9

@tomholub
Copy link

tomholub commented Apr 2, 2020

Here's the relevant conversation.

From our perspective OpenPGP may be the first but not the only use case. Therefore I didn't had in mind to exactly use OpenPGP long IDs (RFC 4880). I need to look deeper in our key derivation function in order to tell how the key ID has to look like.

While what I was mentioning above are (in my mind) serious inconveniences, that at least some users could work around, this one could be a potential blocker.

When decrypting a RFC4880 message, all you have available is the message and the RFC4880 LongIDs the message was encrypted for. That's all. If the hw token was expecting key-ids in some other format for OpenPGP keys, I don't see how user could just respond to "please insert your device with key ID XYZ" and have the message actually decrypted, especially in combination with no way to pull the list of key ids from the device.

Decrypt(to_be_decrypted_data, public_key, HMAC, origin)

I assume, here public_key actually means public_key_id of some sort. But if this has different format than LongID in a way that we cannot freely convert between the two, how to decrypt a received OpenPGP message on a device that did not initially set up the hw token (and doesn't yet have a list of keys ids on it)?

...

Using key ID according to RFC4880: Good point. Still it doesn't require to exactly use long IDs but it might be sufficient to find a way to transfer one into another. I created this separate issue.

@jans23
Copy link
Member Author

jans23 commented Apr 3, 2020

See also #17 for a related design discussion.

@onlykey
Copy link

onlykey commented Apr 3, 2020

Here is the key ID format keybase uses, that might be a good model also using RFC4880 - https://keybase.io/docs/api/1.0/kid

Might not need to store the full 32 byte fingerprint in hardware, if space is an issue last 8 bytes seems like it would be enough for checking, I think that is what keybase uses -
image

@szszszsz
Copy link
Member

szszszsz commented Apr 4, 2020

@onlykey Thank you for linking this. Keybase format looks easy to compute on the device, so we can support it easily. I agree that partial ID could be handy in the case of limited storage.

@tomholub
Indeed the device ID will not suit here for the resident keys, so it should be dropped. The OpenPGP long IDs should be supported natively for them.

As for the derived keys, the idea is to have part of the key source data (e.g. 64 random bytes) on the webservice server (similar to the FIDO U2F/FIDO2 case). That solution allows to manage unlimited keys through the device. This also mean that besides the message and the device, an external server is requred to solve the mapping long ID -> keyhandle, which could be used along with device's secret to compute the private and public keys.
Would this answer your doubts?

@tomholub
Copy link

tomholub commented Apr 5, 2020

@szszszsz Thank you for looping me in, I have some questions to clarify.

As for the derived keys, the idea is to have part of the key source data (e.g. 64 random bytes) on the webservice server (similar to the FIDO U2F/FIDO2 case).

When you say webservice server, you mean our own server-side database where we keep track of derived keys for the client browser - which in turn communicates with the token?

This also mean that besides the message and the device, an external server is requred to solve the mapping long ID -> keyhandle, which could be used along with device's secret to compute the private and public keys.

This likely answers my question above.

If this is your design decision, we'll have to work with it. I'd prefer to not store information for our users if not necessary, but there appears to be no way around it for both resident and derived keys, because even for resident keys I can't pull a list of longids from the device :-/

@szszszsz
Copy link
Member

@tomholub Sorry for the delay. We are in discussion with Jan about that. Will write shortly.

@szszszsz
Copy link
Member

@tomholub
In #19 we are changing the specification to allow to get the public part of the derived keys. This will be merged after the terminology chapter will be completed.

Regarding the derived keys, I have made a little confusion here, specifically with external key handle storage, sorry. Let me try to clear that out.
In #18 we are discussing the function and ways of the key handle in the process of key derivation. The initial idea, as presented in the specification, was to make it possible to derive the key from the master seed, and some key index. The mentioned key handle could comprise of a key index only (e.g. 1, 2, 3), so the additional webservice for storing it may not be needed and with this making it possible to use for a standard OpenPGP case (by using default indexes).
What was not described earlier is that key handle, aside the possibility of storing it externally (does not need to be a secret), could be as well the result of PBKDF2 of an additional password provided by the user (e.g. provided each device session). This will be precised in the specification.
In general we want to compile the use cases list first #15 , so that we know what direction we want to pursue with the derived keys.

I think this would cover better openpgp.js. What is your opinion?

@tomholub
Copy link

This sounds good to me. Thanks for clearing it up!

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

No branches or pull requests

4 participants