10 ms·
I'm a developer, not a cryptographer, and like most crypto articles, most of this post is gibberish to me. I really tried to follow it in the beginning, but the
by skrebbel 7y ago
I'm a developer, not a cryptographer, and like most crypto articles, most of this post is gibberish to me. I really tried to follow it in the beginning, but then I gave up, scrolled to the "what should you use instead", and then realized I didn't understand that either.
If this is article is "easy" crypto, and I shouldn't roll my own crypto, then what should I do? "Just use elliptic curve crypto but make sure you choose the right curve! Here's an abbreviation for you, libsodium has it so you're all set" doesn't comfort me much. I don't have a good intuition of what a curve even is and why my sensitive data can't just go straight ahead like all the other data. I mean, when I call into libsodium with parameters I do not understand, then aren't I, for all intents and purposes, rolling my own crypto anyway? How is any of this of help?
If I want to allow my customers to send me encrypted data via an untrusted channel, then what do I do? I need public key crypto for that, right? Basically, I want the public key cryptography version of Coda Hale's classic blog post about password hashing [0], does that exist?
EDIT: thanks for all the comments folks, great insights! I particularly found [1] by CiPHPerCoder to be a great starting point (akin to Coda's password article) for all kinds of scenarios. I feel much more confident about this stuff now than I did 2 hours ago.
[0] https://codahale.com/how-to-safely-store-a-password/ https://codahale.com/how-to-safely-store-a-password/
[1] https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use https://paragonie.com/blog/2017/06/libsodium-quick-reference...
- cesarb 7y agoThese two articles might help: https://paragonie.com/blog/2019/03/definitive-2019-guide-cryptographic-key-sizes-and-algorithm-recommendations https://paragonie.com/blog/2019/03/definitive-2019-guide-cry... https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html https://latacora.micro.blog/2018/04/03/cryptographic-right-a...
- lvh 7y agoDisclaimer: I co-authored the Latacora one. I think "key size" is something maybe protocol designers need to be worried about, but it's still about two hops above how kobs-set-for-safety I like recommendations I make to be for the median programmer.
- CiPHPerCoder 7y ago> I think "key size" is something maybe protocol designers need to be worried about, but it's still about two hops above how kobs-set-for-safety I like recommendations I make to be for the median programmer. From the article: > The most important thing to keep in mind about cryptographic key sizes in 2019 is they don't matter nearly as much as the general public likes to think. :P The "general public" I'm referring to is the set of people who aren't cryptography protocol designers.
- imiric 7y agoThanks for sharing. Also, this[1] article helped me visualize how ECC works. It's a great read. [1]: https://arstechnica.com/information-technology/2013/10/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/ https://arstechnica.com/information-technology/2013/10/a-rel...
- janekm 7y agoThe article suggests to "use libsodium", with Curve25519.
- RobertRoberts 7y agoI would argue that the comment was more about long term crypto vs one choice. A random person on the internet advising which curve to use (which I don't even know what that is) can be insecure as well. And even if it's a secure choose now it may not be in a few years.
- segfaultbuserr 7y ago> A random person on the internet advising which curve to use can be insecure as well. First, the advise does not come from "a random person". * The recommendation of Curve25519 is originally concluded by its author after evaluating all available elliptic-curve standards under a set of well-defined, objective criteria. The research is published here [0]. * It's not an one-man's claim. This conclusion has been peer-reviewed by many leading researchers and institutions in the past 10 years. There have been enormous amount of discussions made in various communities, including cryptographic developers working on community projects, like OpenBSD [1], OpenSSH [2], Tor [3], industry leaders such as Apple [4], Google [5], Microsoft [6], CloudFlare [7], as well as Internet institutions such as IETF [7], now it's officially part of TLSv1.3. Nearly everyone agreed the security claims by Curve25519 is valid and it offers many desirable properties compared to previous standards. > And even if it's a secure choose now it may not be in a few years. The theoretical security margin is comparable to any other 256-bit ECC encryption, yet it offers a more conservative and robust design against known attacks than other curves, including a good complex-multiplication field discriminant D against potential speedups to Rho Method, immunity against invalid-curve attack, indistinguishability from uniform random strings, and allowing easier, more robust implementations of constant-time (anti side-channel) addition and multiplication. In other words, in theoretical cryptography, there is no known, computationally-feasible way to attack it. Perhaps in the future someone could find a way, but ECC has been thoroughly analyzed in the past 20 years and it's reasonable to believe a major weakness is very unlikely. "You cannot be sure that it cannot be attacked in the future" is not valid logic in applied cryptography. The valid logic is "You only choose something with a high-level of confidence". Currently, the only way to attack is using a quantum computer, but when they come, all the public-key algorithms deployed on the Internet are vulnerable without exceptions (it has been claimed that ECC needs fewer qubits to crack than RSA, that's true. But when quantum computers are large enough to attack ECC, attacking RSA is only a matter of time in the short-term. Giving up ECC entirely today and facing all the potential problems of RSA with long keys for 10-20 years, just to buy a few years of time from quantum attackers is a very questionable sacrifice). Therefore, the research on Post-Quantum Cryptography has already started [8], with possible candidates like McEliece and NTRU. They are expected to replace current standard in the next decade. > which I don't even know what that is WE DO NOT CELEBRATE IGNORANCE. References: [0] https://safecurves.cr.yp.to/ https://safecurves.cr.yp.to/ [1] http://www.openbsd.org/papers/bsdcan-signify.html http://www.openbsd.org/papers/bsdcan-signify.html [2] https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-08 https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-08 [3] https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt?id=b5b771b19df9fc052b424228045409467a7b6414#n81 https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt?... [4] https://www.apple.com/business/docs/iOS_Security_Guide.pdf https://www.apple.com/business/docs/iOS_Security_Guide.pdf [5] https://www.chromestatus.com/feature/5682529109540864 https://www.chromestatus.com/feature/5682529109540864 [6] https://www.microsoft.com/en-us/research/wp-content/uploads/2014/02/curves.pdf https://www.microsoft.com/en-us/research/wp-content/uploads/... [7] https://blog.cloudflare.com/rfc-8446-aka-tls-1-3/ https://blog.cloudflare.com/rfc-8446-aka-tls-1-3/ [8] https://en.wikipedia.org/wiki/Post-quantum_cryptography https://en.wikipedia.org/wiki/Post-quantum_cryptography
- godzillabrennus 7y agoThat basically sums up my experience reading this.
- segfaultbuserr 7y agoIf you really want a minimum implementation that you can understand for educational purposes, perhaps you could try djb's original Curve25519 library to compute a shared-secret. It's extremely simple, a Diffie-Hellman exchange can be implemented within 30 lines of C by calling the library. I think nobody really uses it, but it's the reference implementation of the Curve25519 paper. WARNING: This implementation is probably not secured against side-channel attacks on a modern CPU, offline-use only. https://cr.yp.to/ecdh.html https://cr.yp.to/ecdh.html 1. Computing secret keys. Inside your program, to generate a 32-byte Curve25519 secret key, start by generating 32 secret random bytes from a cryptographically safe source: mysecret[0], mysecret[1], ..., mysecret[31]. Then do mysecret[0] &= 248; mysecret[31] &= 127; mysecret[31] |= 64; to create a 32-byte Curve25519 secret key mysecret[0], mysecret[1], ..., mysecret[31]. 2. Computing public keys. To generate the corresponding 32-byte Curve25519 public key mypublic[0], mypublic[1], ..., mypublic[31], call curve25519(mypublic,mysecret,basepoint); where the constant basepoint is 9 followed by all zeros: const unsigned char basepoint[32] = {9}; 3. Computing shared secrets. Given someone else's Curve25519 public key hispublic[0], hispublic[1], ..., hispublic[31], call curve25519(shared,mysecret,hispublic); Done, you've just got a shared secret. Then you can use standard tools like OpenSSL or "gpg --symmetric" to encrypt the data using AES with that key. But seriously, just use libsodium. It has received extensive audits, its abstraction model is easy to use and understand, while mistakes are hard to make.
- deleted 7y ago[deleted]
- lvh 7y agoWe wrote a blog post for that: https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html https://latacora.micro.blog/2018/04/03/cryptographic-right-a... To answer your specific comments: firstly, you don't need public key crypto. If both you and your sender can agree on a secret key, you can use secret key crypto just fine. For that, use libsodium's secretbox. If you really need public key crypto for some reason, libsodium's box is what you want. What's the "untrusted channel" here? Is this really about encryption in transit, or encryption at rest?
- IggleSniggle 7y agoSuddenly I’m more confused. How can you agree on a secret key, remotely, without some foundational source of trust? I don’t trust the default CA packages anymore, given the prevalence of untrustworthy vendors like Comodo.
- tptacek 7y agoHe’s saying that if you can get away with generating something like a random API key and just having the client save that, that’s much safer than using public key cryptography.
- fireflash38 7y agoMinor clarification: > that’s much safer than using public key cryptography. It's much harder to screw up than using PKC (thereby making it safer). It's something that is really important for UX - you want to make the easiest path the safest path.
- tptacek 7y agoNo. Don't go looking for reasons to use public key where the underlying design doesn't necessitate it.
- lvh 7y agoYes, you need some foundational source of trust, but you were going to communicate that public key one way or another. If you don't trust that medium (let's say it's WebPKI TLS and an adversary gets a bad cert from Comodo somehow), the adversary could just lie about the public key too. A MITM adversary that's in a position to unseal and reseal libsodium secretbox messages can also do that with libsodium box. (For everyone else: just because I'm playing along with this misissuance scenario doesn't mean I don't think ~everyone should trust WebPKI.)
- tialaramex 7y agoTaking you seriously for a moment. You don't need to understand elliptic curve mathematics. As with any other public key crypto system there will be a Private Key which you must never reveal to anyone else, and a Public Key which everybody can be told. They're bits. You don't need to care what those bits mean, if you find yourself using software which expects you to care what the bits mean that's too low level, bail out and find higher level software. Unfortunately Coda Hale's post makes a bunch of assumptions. Reasonable assumptions for a lot of the audience, but they're still assumptions. So an equivalent post has to either make equally broad assumptions OR it has to ask you a bunch of questions. Not crypto questions, but just questions about what you actually want to achieve by having public key crypto. That's going to dictate what you should do. In particular Public Key crypto almost invariably ends up with questions about Identity because of the Public Keys, how do I know this is Bob's Public Key? Do I care about that? Who is "Bob" anyway? Example #1: For a Web Browser the answer is Identity means the Internet DNS hierarchy decides what hosts are named, the Web PKI provides us with an Authority that says this public key belongs to news.ycombinator.com. It's up to the end user to decide whether that's Hacker News or the Disney Company. Example #2: For Signal the answer is that Identity is defined only locally by a user's own "address book" or similar features and they get to decide whether this contact is really "Dad" or "skrebbel" or "Jenny Smith", Signal promises to tell you if "Dad" doesn't have the same public key any more (which is suspicious), but paternity tests or verifying in person that "Dad" isn't just a proxy are your problem. If in fact you "want to allow my customers to send me encrypted data via an untrusted channel" in 2019 you should just set up a secure Web Server, with a Fully Qualified Domain Name your customers know (e.g. write it on business cards, or the sides of vans, or a huge building) with a form on it, where they can submit things. Done. Choose a web server you like and go look at Mozilla's instructions for securing Web Servers.
- cesarb 7y ago> If in fact you "want to allow my customers to send me encrypted data via an untrusted channel" in 2019 you should just set up a secure Web Server, with a Fully Qualified Domain Name your customers know (e.g. write it on business cards, or the sides of vans, or a huge building) with a form on it, where they can submit things. That assumes the customer's browser is trusted, and not configured to silently allow all encrypted connections to be intercepted, decrypted and potentially modified by someone else in the network, which is unfortunately still too common.
- rakoo 7y agoThe "Cryptographic right answers" series is an interesting page, that tells you what to do while still having a little bit of technical information. There are multiple ways to "send encrypted data via an untrusted channel", none of which is perfect, but by descending order of ease of installation and use I would propose this: - Use Signal or Wire to send that data through messages - Use Keybase - Setup an HTTPS server (the default configuration of caddy (https://caddyserver.com/ https://caddyserver.com/) is good enough) - Use the "box" function from NaCl, or libsodium, or Go's reimplementation. Those are all libraries, so it will require actual coding. But those libraries are all made so that misuse is very hard, and you don't need to know or even understand how the crypto works to be able to use it
- FabHK 7y agoIt's all in libsodium. For example, below a pynacl API usage fragment, abridged from their docs [1]. No crypto parameters or nonces or authentication are exposed. Modern crypto is really relatively easy to use. (What's never trivial is key management, how do you get Alice's public key, but that's hard with any sort of public key cryptography.) # Generate Bob's private key, which must be kept secret skbob = PrivateKey.generate() # Bob's public key, and similarly for Alice... pkbob = skbob.public_key # Bob wishes to send Alice an encrypted message so Bob must make a Box with # his private key and Alice's public key bob_box = Box(skbob, pkalice) # This is our message to send (binary blob of data) message = b"Kill all humans" # Encrypt our message encrypted = bob_box.encrypt(message) [1] https://pynacl.readthedocs.io/en/stable/public/ https://pynacl.readthedocs.io/en/stable/public/
- lvh 7y agoFWIW the cool API here that PyNaCl exposes (but not every libsodium impl) is automatically selecting the nonce for you.
- FabHK 7y agoIndeed, the documentation mentions it and does expose it, but I abridged it out to show how trouble-free the default implementation is.
- jj11837 7y agoThe last thing you should start with is "it's all in lobsodium". You didn't understand the point. "how do you get Alice's public key, but that's hard with any sort of public key cryptography." That sentence makes absolutely no sense, it's a public key, why would it be hard to send? The problem is people are like "just use product X, you don't have to understand it". Marketing wanketeering is what makes crypto more difficult in the first place. No one gives a shit about shipping your product. "Just use libsoduium" is an easy way to add to the problem.
- adrianN 7y agoThe hard part about getting Alice's key is making sure that it's actually Alice's.
- edwardr 7y agoTry reading up this guide for a great intro into application level crypto... https://tozny.com/security-guides/ https://tozny.com/security-guides/
- mirimir 7y agoOK, so how do you use libsodium in ssh?
- kebman 7y agoElliptic curve cryptography (ECDSA) is what's used in Bitcoin (Secp256k1).
- mtgx 7y agoThis is a good guide for which one to choose: https://safecurves.cr.yp.to https://safecurves.cr.yp.to
- tabletopneedle 7y agoTl;dr Curve25519 for 128-bit security, to use with 128/256-bit symmetric cipher. X448 for 224-bit security to use with 256-bit symmetric cipher. - For symmetric ciphers choose any of the three below: -ChaCha20-Poly1305 -Salsa20-Poly1305 -AES-GCM.
- hinkley 7y agoYou should read Bruce Schneier. He generally explains why you should care. His book is pretty good too. The first third is general theory before he gets into implementations, and it's worth buying even if you never read past the halfway point.
- bsder 7y ago> If this is article is "easy" crypto, and I shouldn't roll my own crypto, then what should I do? X25519, Ed25519, XSalsa20-Poly1305--you just minimized your footguns. Unless you have a different library accessible, use TweetNaCl or one of its wrappers--now you've minimized your library footguns: https://tweetnacl.cr.yp.to/ https://tweetnacl.cr.yp.to/ If the operation you want to do isn't part of that library, you need to ask yourself: "Do I truly understand the security implications of what I am try to do?" And then not do it. There are still lots of implementation footguns (leaking values in memory, side channel attacks, etc.), but those 2 choices put you so far ahead of the pack that your can probably survive until you have enough money to actually pay a cryptographer to come review your stuff.
- cyphar 7y ago> XSalsa20-Poly1305 I'd suggest ChaCha20-Poly1305 in the AEAD construction defined in RFC 7539[1] (which is what most new libraries implement). ChaCha20 is more performant and these days is more widely used -- though the underlying construction is very similar and both were designed by Bernstein et al. [1]: https://tools.ietf.org/html/rfc7539 https://tools.ietf.org/html/rfc7539
- jillesvangurp 7y agoCrypto can indeed be intimidating for ordinary developers. Discussions tend to be dominated by very technical arguments about algorithms, math, and "my crypto is better than yours" type arguments. Not always that productive. I tend to look at things like "how easy is this to use", "are good implementations available", and "what are smart people saying that I should probably listen to". The consensus of not doing your own crypto is decades old at this point and still good advice but also a bit of a cliche. I don't come across a whole lot of projects actually doing their own algorithms. The opposite actually. People just blindly copy paste dependencies and code they think is good enough. Despite the tone of the article (and its length), the advice is actually sound. RSA has been around quite long; can be quite complicated to deal with when integrating and definitely has a few pitfalls; mainly because it leaves a lot of things as an exercise to the developer and thus plenty of room to do it wrong. I recently came across ECC and the curve they recommend in the article in Stellar (which uses it) and had to write a bit of code to figure out how to work with keys; this turned out to be very easy. What I like here is that from a developer point of view there's not a lot to configure here and when you use it as a black box that's a good thing. Basically key generation is generating a single random number. Which of course you should do using a secure random generator. You then calculate the public key from this secret. End of story. You probably want some tests around this to verify that you can work with some known key but this basically either works or doesn't. The only thing I found slightly worrying was the lack of standard/commonly used implementations for different languages. For example, the Stellar Java SDK for stellar pulls in a library (net.i2p.crypto:eddsa) from the i2p project in version 0.3.0. I actually fixed a minor bug at some point to at least get rid of a fork of this that they were using but this suggests to me that there might be some issues lurking out there with not so great implementations. The discussion for the relevant ticket to implement this in OpenJDK suggests that there are some not so trivial aspects to a proper implementation: https://openjdk.java.net/jeps/324 https://openjdk.java.net/jeps/324. This only landed in v11. If you are targeting e.g. Android (like Stellar is), you'd need some third party implementation. I've looked around and there are a few alternate implementations at this point for java and other languages but nothing that I would consider very mainstream yet. So, ECC curve 25519 looks easy to use but the implementations are all over the place in terms of maturity. That in itself should still be considered a red flag and sort of goes against the advice of not rolling your own crypto; which is effectively what you are doing when pulling in other people's libraries in really early versions.
- techslave 7y agoI know this late to the party, but no one has responded to this: > If this is article is "easy" crypto, This article isn’t “easy” crypto. If you expect to understand it, you should already understand how (mathematically) RSA works.