My apologies for the delay in replying; I’ve been busy taking time off and spending 4th of July weekend with my family. I’ll write a reply to this soon, it’s just that it will probably be a long one ;)
> On Jul 4, 2016, at 1:24 PM, Frank Siebenlist <frank.siebenl...@gmail.com> > wrote: > > To make it a little more real, please look at this gist: > > https://gist.github.com/franks42/b8b28049adcdf4504271238391c3525b > > which implements a key identifier generation based on HKDF. > > Any security concerns with such an approach? > > Better alternatives? > > Thanks, Frank. > > > > On Sat, Jul 2, 2016 at 4:52 PM, Frank Siebenlist > <frank.siebenl...@gmail.com> wrote: >> Hi Laurens, >> >> I'm afraid that I have not been very good in explaining my use case, because >> the questions you ask point at more complicated solutions than I thought >> were necessary. >> >> The aim is to find the most convenient symmetric key identifier to embed in >> a cipher message that would require the minimum amount of key management. >> >> What is best depends on the context. Sometimes it's easy because there is >> only one key, or the security context is so unambiguous that associating the >> right key is trivial. Other times it's a bit more challenging. We have an >> existing application with tens of long-lived keys, and the current >> key-management complicates key-rotation and upgrades to modern algos and >> such. >> >> If both Alice and Bob can generate key identifiers (kid's) from the key that >> they share directly, like derive if from the symmetric key, then there is no >> need to exchange or agree upon a name for that key as it would be kind of a >> "true name" (read Vinge if you haven't ;-) ). The parties only have to agree >> on the key identifier derivation method. >> >> For example, if Alice and Bob agree to name their symmetric keys by taking >> the sha256 of that key's bytes, base64url encode the hash, and represent it >> as a urn, like "urn:s256:V2jyhd8tX-19vpEhyrDzIHgUYyDA5MS1Qi71iw1SUP0". This >> would allow both parties to maintain their own key-db with (kid, key) >> associations. Embedding the kid in the exchanged cipher messages would allow >> both parties to easily find the key to decrypt the received message. >> (very much like we often use the hash of the public key (or pk-cert) to >> identify the private key to decrypt) >> >> The kid embedded in the cipher message is no more than a “hint”. It could be >> signed as part of the whole cipher message, but its integrity can only be >> confirmed after the message is decrypted&authenticated. Changing the kid in >> a cipher message results in DoS, but so would flipping any other bit in that >> message. >> >> In its most simple form, I believe that the kid-derivation could be a sha2 >> of the key as long as the key is "truly" random. The only concern may be >> that some use a simple hash of the key for key derivation...(?). To avoid >> any of those usage collisions, you could define the convention of >> pre-pending the key with some publicly know constant, like >> b'pre-kid-constant' or fancier. >> >> If one believes that a simple sha2 hash is only borderline enough secure >> (?), then maybe use a CMAC or HMAC, where you use the key on the key-value >> itself, and the resulting tag would constitute the identifier. (I did >> something like that in franks42/naclj with blake2) >> >> Or use HKDF, with maybe a kid-derivation specific constant for the salt, a >> kid-specific info value, and a sufficient length of the resulting key, i.e. >> identifier, that makes everybody happy. >> >> Maybe something based on HKDF would be best (?). >> >> Hope this additional explanation helps. >> >> Thanks, Frank. >> >> PS. Don’t believe I will resurrect that franks42/naclj - I’ll add a note >> about depreciation and send them to your effort - it was a good experience >> learning about Curve/Ed25519 and the nacl/libsodium code though - also >> trying to keep all data structures as immutable as possible was a good >> exercise. >> >> >> On Fri, Jul 1, 2016 at 3:53 PM, lvh <_...@lvh.io> wrote: >>> >>>> On Jul 1, 2016, at 12:54 PM, Frank Siebenlist <frank.siebenl...@gmail.com> >>>> wrote: >>>> >>>> Hi lvh, >>>> >>>> Guess you're the "lvh" who is responsible for "lvh/caesium" ;-). >>> >>> Yup. I’m also a founding member of PyCA and the resident cryptographer, >>> which is why I’m on this list :-) >>> >>>> Good to see that you've reanimated that project! Believe you were kind of >>>> distracted for awhile, which "forced" me to play around with >>>> "franks42/naclj"... which has been on live-support for about a year >>>> now, because my new job consumes even my playtime. >>> >>> It did what I needed it to do at the time, so I didn’t fix what wasn’t >>> broken ;-) I don’t recall anyone reaching out or filing issues. Once >>> someone did ask questions and contributed code, I was happy to >>> merge/review/cut new releases/do new development. More dev is happening now >>> to scratch my own itch :) >>> >>> Currently I’m doing a lot of work around NMR as mentioned before, and API >>> design around e.g. different byte buffer types, so that for example you can >>> efficiently dump a nonce and a ciphertext in the same buffer, or derive >>> multiple keys in one iteration of BLAKE2, etc. Also a bunch of work around >>> e.g. pinning and verification of the produced binding and related >>> benchmarking :) >>> >>> I invite you to look at caesium again, because some of the criticisms you >>> make in naclj’s README no longer apply (e.g. caesium no longer uses kalium >>> and instead binds libsodium directly, albeit for a different reason than >>> what naclj mentions). Because the binding is done in Clojure, it can do all >>> sorts of metaprogramming including binding every permutation of a >>> particular method for various byte types in addition to the inspection >>> mentioned above, e.g.: >>> https://github.com/lvh/caesium/blob/master/src/caesium/binding.clj#L56-L62 >>> >>> Do you intend to continue to develop naclj, or is it effectively retired? >>> >>>> As part of that "franks42/naclj" effort, I suggested to standardize >>>> the derivation of a kid from the two curve25519 public keys. However, >>>> I recognize that you do not always have any DH-keys available when you >>>> have a bare symmetric key, >>> >>> Is that scheme documented anywhere? I wonder what the use case is for two >>> curve25519 pubkeys — the “obvious" case would seem to easily degenerate to >>> the shared symmetric secret (after doing a DH exchange). >>> >>>> so I suggested a scheme based on blake2. I >>>> wrote up some rationale for those choices here: >>>> "https://github.com/franks42/naclj/blob/master/Keys%2C%20IDs%2C%20and%20URNs.md", >>>> but never got much traction on the libsodium list,... and then I got >>>> distracted. >>>> >>>> Now I'm faced again with similar key-management issues, which could >>>> benefit from such key-derived kid's - so I try again. >>>> >>>> In summary, your suggestions all resonate very well, but... there are >>>> too many of them. Let's just pick one identifier derivation mechanism >>>> for symmetric keys, document it, implement it, use it! >>> >>> I think there are a few problems preventing this from happening right now, >>> including: >>> >>> - Historically, cryptographers have not researched key wrap anywhere near >>> as much as other schemes. I think the only reason it’s en vogue now is the >>> interest in NMR, which at least a handful of cryptographers (Rogaway, >>> Krovetz, and humbly, myself) care about now, and is incidentally a related >>> problem. >>> - People want subtly different things for their protocols, further reducing >>> interest. Do you just want to identify a key? That’s fine, but a problem >>> many protocols dodge. Do you want to ship a key to someone who already has >>> a secret or asymmetric key? AEAD (including NMR AEAD in particular, so key >>> wrap) and just asymmetric encryption (a la non-PFS TLS or GPG) is probably >>> where you’re going to land. >>> - How does this fit in a grander protocol and what is that protocol trying >>> to accomplish? >>> - How is the key identifier authenticated? What prevents Mallory from just >>> modifying the key id bytes to effectively deny service? E.g. if I’m doing >>> this to make sure I can rotate keys effectively, how do I auth that? >>> Ideally without replacing an unrotatable secret key with another >>> unrotatable secret key :D (Effective key rotation for KEKs is definitely >>> something I care about.) >>> - When keys are being sent alongside messages, how do we make this not a >>> footgun for e.g. key selection attacks? (Granted, harder for EdDSA, but I >>> want protocols to be correct for arbitrary schemes :)). PyCA cares about >>> recipes being not footguns. That’s a mixed bag: on the one hand, it means >>> we can give safe advice, on the other hand, it does mean that all we have >>> is Fernet... >>> >>> Overall, I think this is a reasonable idea for some protocols, but I think >>> we need to be extremely clear about what that is, who it’s for, and how to >>> use it. >>> >>> >>> lvh >>> >>>> Groetjes, Frank. >>>> >>>> On Fri, Jul 1, 2016 at 9:51 AM, lvh <_...@lvh.io> wrote: >>>>> Hi Frank, >>>>> >>>>>> On Jul 1, 2016, at 11:11 AM, Frank Siebenlist >>>>>> <frank.siebenl...@gmail.com> wrote: >>>>>> >>>>>> snip snip key identifiers >>>>> >>>>> This is why some key derivation functions and PRFs have “purpose” or >>>>> “info" fields, yes; including BLAKE2 and HKDF. Deriving a lesser key >>>>> (which might just be a keyid) is a perfectly valid strategy from objcap >>>>> practice. I’m doing something similar in the scheme of a larger >>>>> semiprivate key scheme using libsodium. You probably do want something >>>>> that explicitly supports that instead of just implicitly picking a >>>>> particular nonce or whatever — I’m not sure which nonce you’re referring >>>>> to, I don’t think the systems you mentioned take one. TL;DR: make the >>>>> derivation completely distinct based on what you’re deriving and why >>>>> you’re deriving it :) >>>>> >>>>> You might also want to look at the related concept of NMR and key-wrap, >>>>> which might let you solve the problem at a slightly different part of >>>>> your protocol; essentially giving you a protected key with associated >>>>> data about that key. It’s not entirely clear what the people >>>>> standardizing GCM-SIV want to do exactly (other than “not TLS”, I don’t >>>>> think they’ve said), but this is the obvious choice, especially given >>>>> GCM-SIVs separate code path for tiny messages and the historical linking >>>>> of the two from a crypto design perspective. >>>>> >>>>> I am also writing NMR stuff on the side in libsodium/caesium, but that >>>>> focuses mostly on being a Fernet replacement, rather than a keywrap, >>>>> using secretbox (which makes it easy because big nonce space). Pretty >>>>> sure I can translate it to the AEAD schemes, but the security proof gets >>>>> iffier. Which reminds me: we should talk about Clojure bindings to >>>>> libsodium some time :) >>>>> >>>>> >>>>> lvh >>>>> _______________________________________________ >>>>> Cryptography-dev mailing list >>>>> Cryptography-dev@python.org >>>>> https://mail.python.org/mailman/listinfo/cryptography-dev >>>> _______________________________________________ >>>> Cryptography-dev mailing list >>>> Cryptography-dev@python.org >>>> https://mail.python.org/mailman/listinfo/cryptography-dev >>> >>> >>> _______________________________________________ >>> Cryptography-dev mailing list >>> Cryptography-dev@python.org >>> https://mail.python.org/mailman/listinfo/cryptography-dev >>> > _______________________________________________ > Cryptography-dev mailing list > Cryptography-dev@python.org > https://mail.python.org/mailman/listinfo/cryptography-dev _______________________________________________ Cryptography-dev mailing list Cryptography-dev@python.org https://mail.python.org/mailman/listinfo/cryptography-dev