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

Root namespace #2

Open
tarcieri opened this issue Sep 27, 2019 · 6 comments
Open

Root namespace #2

tarcieri opened this issue Sep 27, 2019 · 6 comments

Comments

@tarcieri
Copy link
Collaborator

Assuming CryptoURIs are URI/URN-like namespace starting with:

crypto:

What goes in the toplevel namespace following that prefix?

The current Rust implementation places everything into:

  • crypto:public:
  • crypto:secret:

Are those names too long? Should there be more options than just that?

What information is important to convey in this namespace?

@tarcieri
Copy link
Collaborator Author

Answering my own question here, reflecting on my previous design, I have these thoughts:

  • public and secret are too long: shorten them to pub and sec
  • Not everything clearly and unambiguously fits into either of these categories

In broad strokes, I think it should be:

  • crypto:pub:
  • crypto:sec:
  • crypto:<other>

Where <other> is anything which doesn't clearly fit into "public" or "secret" categories. Case-in-point: crypto:hash and crypto:sig for digests/hashes and signatures respectively, where a hash may be a credential/solution to an authorization problem (e.g. HTLC/HTLA), or a signature the "witness" to a similar problem.

Base on that, the concrete root namespace would look like:

  • crypto:pub:
  • crypto:sec:
  • crypto:hash:
  • crypto:sig:

Additional items from #1:

  • Message Authentication Codes (MACs) - i.e. outputs from a MAC algorithm / "tags": crypto:mac ?
  • Password-hashing function digests: belong in crypto:sec IMO
  • Message ciphertexts: are their own can of worms, and perhaps not the best fit for CryptoURI. Punt for now?

@dhaavi
Copy link

dhaavi commented Sep 27, 2019

I really like how CryptoURI supports users in telling them the nature of the object they are interacting with (see #1): Is this public? Is this a secret I need to protect? I think this a great way to reduce user error.

Now, the pub and sec namespaces make a lot of sense to me.

I am not sure if ciphertexts need a CryptoURI at all. Or maybe we can use something generic as crypto:data and just base64/bech32 append the output of an encryption operation.

I am trying to think through the user process here:

crypto:sec:key:aes128gcm://<key|bech32>/encrypt + The quick brown fox jumps over the lazy dog = crypto:data:<output> or just a binary blob?.

or

crypto:sec:key:ed25519://<private_key|bech32>/sign + The quick brown fox jumps over the lazy dog = crypto:sig:ed25519://<public_key?>/<metadata>/<sig>

These examples brought up more questions:

  • The scheme is hierarchical, but is the path? Looking at crypto:sig:ed25519 the order within the path probably does not matter.
  • Do paths with key schemes have any "action" included, as I hinted at with /encrypt and /sign?

Am I going in the right direction here?

Further, thinking about these two examples, do we really need the sec namespace? Is there any other namespace than key in it?
You mention crypto:sec:pwhash in #1.
Would crypto:key and crypto:password also work? Primarily: Does key and password imply secret enough, that people will understand that these are to be kept secret?

@tarcieri
Copy link
Collaborator Author

tarcieri commented Sep 27, 2019

I am not sure if ciphertexts need a CryptoURI at all.

+1 with one caveat: "key wrapping" (see below)

crypto:sec:key:aes128gcm://<key|bech32>/encrypt

Just a quick note on this: when a derivation hierarchy isn't in use, I've made these look more like a URN in the current implementation (these won't be valid Bech32 as I'm doing secret -> sec but):

  • crypto:sec:key:aes128gcm:z965e4e2ascfhaf0w6rjzt5f2udmdwyw
  • crypto:sec:key:aes256gcm:k5k9qk3h678d5hwnfusvyf2qagd4393ulrjmlrl6shulyjf9qk6qw4eutf
  • crypto:sec:key:ed25519:n4smr800l4dxpw5yft6f9mpvc3zyn3tf0vexjxts8wkqx89w0asqm8kt36

[Hierarchical stuff] Am I going in the right direction here?

The only hierarchical feature I wanted to support via the URIs themselves is specifying paths within a derivation hierarchy (e.g. BIP32 / HKD32), not necessarily using that to encode additional information like usage patterns. I'd suggest using the "query" section of the URL to encode that information if necessary.

Further, thinking about these two examples, do we really need the sec namespace? Is there any other namespace than key in it?

You mentioned password hashes already. OTP seeds would be another example.

I'd break this down as follows:

  • All secrets are prefixed with crypto:sec
  • There are two different types of keys: public and secret/private. It should be immediately obvious which is which. Some precedent from PKCS#8:
-----BEGIN PRIVATE KEY-----
-----BEGIN ENCRYPTED PRIVATE KEY-----

Note: as I mentioned on #1 I very much want CryptoURI to support "key wrapping" for other CryptoURIs, be it with a key-encrypting-key (KEK), or a password.

Does key and password imply secret enough, that people will understand that these are to be kept secret?

No. There are two types of keys: public and secret. I do want to very much want to make it easy for users to tell the following:

  • This object represents a cryptographic key
  • This object is a secret

@dhaavi
Copy link

dhaavi commented Oct 2, 2019

I'd suggest using the "query" section of the URL to encode that information if necessary.

So how would you combine a URN with usage patterns?
crypto:sec:key:aes128gcm:z965e4e2ascfhaf0w6rjzt5f2udmdwyw:action=encrypt
This looks a bit funny, and I'm not sure this is actually valid.

Or would you want to shift the key into the path in this case and use a URI?
crypto:sec:key:aes128gcm://z965e4e2ascfhaf0w6rjzt5f2udmdwyw?action=encrypt

A couple thoughts on this:

  • I'd advise against multiple formats for the same thing. (my suggestion, I know)
  • I also don't know if using both URIs and URNs is helpful for simplicity. Normally, for a standard URI, I would not expect any variable data in the scheme. (I know that's okay with URNs)
  • Exclusively using a URI would enable cryptoURIs to be opened with a default application on some systems. Eg. you could click on a CryptoURI on a website and it'll open your default application to handle that and it will decrypt a private message for example.
  • Using URIs would create a nice way to distinct between an algorithm and a data object:
    • Specific algorithm: crypto:sec:key:aes128gcm
    • Key of type algorithm: crypto:sec:key:aes128gcm://z965e4e2ascfhaf0w6rjzt5f2udmdwyw

Please move the URN/URI discussion to a separate issue if you feel it's too off topic here.

No. There are two types of keys: public and secret. I do want to very much want to make it easy for users to tell the following:

Okay. Good call.

To recap:
So, I think we end up with this then?

  • crypto:pub:
  • crypto:sec:
  • crypto:hash:
  • crypto:sig:

At least for the first iteration.

@tarcieri
Copy link
Collaborator Author

tarcieri commented Oct 2, 2019

URNs begin with urn: (further increasing the length), and follow their own set of rules (e.g. namespace registration), so when I say "URN-like", I don't mean a full fledged URN, but a URI roughly formatted like one.

I wasn't suggesting two syntaxes (regardless it's all URI generic syntax, and a URN is a type of URI), but a way to specify a hierarchical namespace within a key. So more like:

No hierarchy

  • crypto:sec:key:aes128gcm:z965e4e2ascfhaf0w6rjzt5f2udmdwyw
  • crypto:sec:key:aes128gcm:z965e4e2ascfhaf0w6rjzt5f2udmdwyw?action=encrypt

Hierarchy

Some options:

  • crypto:sec:key:hkd32:aes128gcm:z965e4e2ascfhaf0w6rjzt5f2udmdwyw://foo/bar/baz?action=encrypt

Makes the hierarchical namespace purely additive, well except for the query string

  • crypto:sec:key:hkd32://aes128gcm;z965e4e2ascfhaf0w6rjzt5f2udmdwyw/foo/bar/baz?action=encrypt
  • crypto:sec:key:hkd32:///aes128gcm;z965e4e2ascfhaf0w6rjzt5f2udmdwyw/foo/bar/baz?action=encrypt

Inspired by RFC 6920: Naming Things with Hashes, which uses ni:///<algorithm>;<base64uri digest> syntax


...but perhaps we can move the question of syntax for hierarchical keyspaces to a separate issue, and make some tentative decisions on the core issue here.

So, I think we end up with this then?

  • crypto:pub:
  • crypto:sec:
  • crypto:hash:
  • crypto:sig:

At least for the first iteration.

👍

tarcieri added a commit to cryptouri/cryptouri.rs that referenced this issue Oct 7, 2019
...based on the discussion in this thread:

cryptouri/cryptouri-spec#2

Changes:

- `crypto:public:digest` => `crypto:hash`
- `crypto:public:key` => `crypto:pub:key`
- `crypto:secret:key` => `crypto:sec:key`
- `crypto:public:signature` => `crypto:sig`
@tarcieri
Copy link
Collaborator Author

tarcieri commented Oct 7, 2019

I just implemented this updated namespace in the Rust implementation:

cryptouri/cryptouri.rs#14

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

2 participants