(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/No, because with symmetric encryption you'd have to protect the key against theft and tampering (i.e., against reading and writing by a third party), while you only have to protect an asymmetric public key against tampering, which is a lot easier in practice.
(also not an expert, just my understanding of it)
Choice 1: use a symmetric keys. This means one key per device, which you have to manage. Quite cumbersome. You could instead have one symmetric key for everyone, but then if only one IoT device gets compromised (which over time is a virtual certainty) the whole crypto system would be compromised.
Choice 2: use a public/private key pairs. One for the server, and one for each device. Now the system is only broken when the server key is compromised. If a device gets compromise, the attacker merely learns the server's public key, and can impersonate that particular device.
The main advantage of choice 2 vs choice 1 is that with Choice 2, you can use the same server key for everything. You'd still use a protocol with ephemeral keys, but you wouldn't have to manage many many keys. And if the IoT devices are untrusted (that is, they are assumed compromised or anonymous), the whole system only has to manage one key.
Now sure, you could still make it more performant by retaining symmetric keys around. And you'd have to perform fast key erasure (replacing the key by a hash of the key) from time to time to ensure forward secrecy, but with public keys around the symmetric key can act as a cache, which can safely be erased whenever you restart or update your system.
I guess it doesn't protect against something attacking and snooping on your machine though.
If there are no public keys pinned to clients (say secure messaging apps like Signal where each user generates their own keys), users need to check the public key fingerprints to make sure there's no MITM attack taking place.
So very likely unless Bob is comfortable with this situation he stills need a mechanism to find out who he's talking to. On the upside he does now have an encrypted channel on which to continue the work.
At scale that only practical answer is an Authority, a Trusted Third Party, people _so_ trustworthy that Alice, Bob and maybe even Mallory agree that they know who is who. In one sense this is so hard it might be impossible. But then again maybe it works anyway?
If you don't need scale, for example maybe you're a conspiracy of a few dozen people trying to bring down the Authority, then you have lots of other options depending on your circumstances including Out of Band verification and the Socialist Millionaires Protocol.
If you are a college kid and convinced that everybody on your Facebook friends list, and everybody on their Facebook friends lists, is a fundamentally good person - but that the Authority is a shadowy conspiracy against you all, you can use the Web of Trust, right up until the guy who once lived with a friend of your cousin's housemate steals your life savings and leaves you in a bathtub filled with ice with a hole where one kidney used to be.
The difficulty you are describing assumes a user base of crypography pedants who make assumptions about third parties that don't matter to 99% of non-technical users (nor even technical users in many cases).
One example: you work for the American government, and you witness something very wrong, very illegal going on. You'd better be sure, when contacting Laura Poitras, that you are indeed contacting Laura Poitras, and not some counter-intelligence operative from the NSA.
And it has to work even if you don't have Ed Snowden's skills. Without reliable crypto the rest of us can use, people will get caught, arrested, tortured, killed blackmailed… just for speaking up.
Maybe we don't want reliable crypto to be widely available. Maybe we want to have mass surveillance. But that's another debate. (Personally, I'd rather have everyone to have reliable crypto, and I'm willing to make wiretapping impossible in the process.)
How to beat Laura Poitras publishing a public key all over the place?
Without forward secrecy, getting Laura Poitras' key will enable the NSA to read all past communications. They only have to seize her computer when it's still on, and the key is still in memory somewhere, or compel the poor journalist to give up here keys (possibly using that "non invasive" waterboarding torture, and justifying it with suspicion of helping terrorists).
Now if Laura kept the decrypted messages in her laptop, forward secrecy wouldn't do anything, but if she properly deleted them, it would be a shame if the messages were nevertheless at the mercy of the attacker.
---
As for key finding, well… the simple solutions do work pretty well. Snowden for instance didn't find Poitras' keys lying around on the internet. He asked someone he trusted would give him the right key.
It isn't real ambiguous.
For instance, Snowden had someone tweet a key fingerprint: https://theintercept.com/2014/10/28/smuggling-snowden-secret...
https://lwn.net/Articles/464137/
Hint: TOFC is a lot like what I described above, with the added usability that you don't have to type "yes" every time like a chump.
Oh god but how do you ask her without a guarantee that she's really who said yes?
Even if you meet Alice in real life to ask, how can you be sure the meeting isn't a dream or a simulation and the Alice before your eyes isn't a chosen plaintext attack by a cosmic man in the middle?!
The entire science of cybersecurity is bankrupt and founded upon untenable foundations!!
The point of the article is all the ways RSA blows up. libsodium addresses that style of problem. Saying there are other problems ("how do we agree on a key") may be true, but isn't responsive to the discussion.
Same goes with crypto. It's fine to learn the concepts of how to use a trusted library, but you really aren't likely going to understand the underlying tradeoffs and mathematics.
People here aren't just saying "just use product X", they're saying, "learn the concepts of product X and use that". That's about as good as it's going to get for any specialized, complicated domain.
Yes, of course it is. Doctors know a lot, but they're not competent to assess the pharmaceutical literature.
So here's how it works. In med school, drug manufacturers provide free equipment, food, liquor, etc. And push their drugs. Because once you have someone in the habit of prescribing some drug, they tend to keep prescribing that drug.
Also, you pay influential doctors to deliver talks at conferences, praising your drug(s). You also pay ghostwriters to draft papers, which said influential doctors can submit for publication.
And last, you pay sexy, charismatic young things (of both sexes) to visit doctors' offices, pushing your drugs, and giving away food and stuff.
It is possible (even more likely) to have experts with legitimate opinions that are scientifically valid and have measurable outcomes that also correspond to commercial interests. Ie. "it helps people and makes money".
That model has worked for over a century. Yes, it's under attack by unethical people (more than in the past?), but I'm not sure what the alternative would be.
For example, I recall reading that well over half (maybe 70%-90%) of the medical literature on Neurontin (gabapentin) were ghostwritten advertorial spam funded by Novartis.
When someone says something that doesn’t make sense to you, do you just put whatever they’ve handed you into your mouth without asking questions?
On the other hand, getting crypto advice from random bloggers and HN commenters is akin to getting a medical treatment plan and drugs from random bloggers and HN commenters.
If you can't be bothered to read their profiles or understand who they are, I refer back to my point about arguing from a position of ignorance.
To be honest, this is literally the level of discourse of most Hacker News discussions about healthcare.
I have doctors in the family. The scariest stories of "marketing wankateering" in medicine I hear is from them.
Obviously not. So, where is the line drawn of what professional opinions are or are not trusted?
There's no doubt that "marketing wankateering" happens in all complex domains. Any "Market for Lemons" (i.e. a market with information asymmetry - a domain so complicated or obfuscated that consumers can't understand its fundamentals) will be exploited by charlatans. This is why we have professional (imperfect but functioning) backstops such as medical scientific research and the security/crypto research community.
OP was claiming that not even the professionals on this thread can be trusted to not be "wankateers" for a free/open source library, with no evidence, or even a hint of moderate understanding of the problem domain (i.e. why it's hard to distribute a public key), or desire to learn. Perhaps they were just frustrated with the complexity of the domain, but flaming people trying to help as being "wankateers" is rather fatalist.
Arguing from a position of ignorance when people say something that doesn't make sense to you is literally how anti-vaxxing happens.
Just because arguing from a position of ignorance can sometimes produce outcomes which align with your personal anecdotes doesn't make it an intellectually valid method of discourse.
Anti-vaxxer beliefs aren't caused by people questioning the first medical advice they get from a medical professional when it doesn't sound right to them. Anti-vaxxer beliefs come from either not verifying and going with your gut, or verifying and then ignoring what you've learned.
Doctors are humans and make mistakes sometimes, and your own health is your own responsibility. So is safety of your own application, so you shouldn't plug in someone else's crypto if you don't feel comfortable with it, but instead try to understand the domain as much as you need to start feeling comfortable.
...which is exactly what "arguing from a position of ignorance" means. Once you attempt to verify medical advice (in good faith) you are no longer ignorant.
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.
I believe you're talking about:
https://wiki.mozilla.org/Security/Server_Side_TLS and/or https://infosec.mozilla.org/guidelines/web_security
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.
That just means someone else on the network securely sent you stuff...
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.
Also, this[1] article helped me visualize how ECC works. It's a great read.
[1]: https://arstechnica.com/information-technology/2013/10/a-rel...
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?
(For everyone else: just because I'm playing along with this misissuance scenario doesn't mean I don't think ~everyone should trust WebPKI.)
> 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.
Mail is another option, depending on how secure you think that is.
Cryptography is often not about "uncrackable" but about confidence in security over a foreseen interval.
On the 4th of June 1943 the details of Operation Neptune ("D-Day") were a priceless secret of the Allied Command, a break that allowed Berlin to know the plan could have resulted in the invasion force being expected by a heavily prepared and well-reinforced German defence. Those who made it back to England alive would have no reward for their efforts.
By the 7th of June 1943 plans for Neptune were a historical curiosity of little military value.
And I did mean Neptune, the Overlord plans would have remained valuable for several weeks as they included details of the immediate objectives in Normandy and how resupply would be done, Neptune was just the invasion and related actions.
However, just because you have a channel that can't be MitM-ed doesn't mean you can actually trust whoever is on the other end. The problem of "how do you know you trust the other end" requires some foundational source of trust, whether that's trusting the transportation medium (that the person you handed the USB key to is actually who he/she claims to be), the issuer (could be yourself), and so on.
Considering it took me 8 months to not even finish my own, making several serious mistakes in the process, even though I wrote my own goddamn crypto library and am standing on Noise's shoulders…
I tend to agree.
That said, we still have a problem: `crypto_box()` is nice, but it doesn't have any kind of forward secrecy, identity hiding, or key compromise impersonation resistance. Sure, offline protocols can't really have that (the best you can do is use signatures to avoid the key compromise impersonation issue, but then you loose some deniability). Online protocols however, can.
But then what do we do? We could use Noise, (the Noise explorer now generates code in several languages), but you at least have to chose a pattern. Which one? How can you even notice that XK1 maximises client anonymity, and IX (properly used) maximises server security? Even if you know that, which are you going to use?
And I'm not even talking about implementing your Noise pattern, should existing implementations not suffice (maybe you want to leverage a custom crypto library optimised for some embedded processor). Noise isn't simple. A serious drawback in my opinion.
This, if I guess correctly, is what led you to recommend that horror that is TLS for client/server security. Because the burden of choosing a reasonable TLS library, of properly configuring that TLS library to only use TLS 1.3 with a limited set of ciphers (possibly just Curve25519 and ChaPoly)… still remains less error prone than picking up a Noise protocol. <PKI matters conveniently left out>
That situation is deeply unsatisfactory. It's all well and good to tell people "don't make your own kex", but if you don't at the same time point them to an existing kex, they will be less likely to follow your advice. I mean, I didn't.
The confusion is that IES/ElGamal sometimes means a family of systems and sometimes someone literally means FFDH + AESCTR or something. The abstract concept is fine, but you should use a hardened implementation.
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.
I mean the first hit starts with this sentence: "Ed25519 keys can be converted to X25519 keys, so that the same key pair can be used both for authenticated encryption (crypto_box) and for signatures (crypto_sign)."
I have no idea what do to next.
The first example shows both sides of the communication. The public keys are shared (but you want to make sure that you have the correct one, for example by meeting the recipient in person and comparing the keys). The library defaults in libsodium are already chosen to be secure (using Curve25519 and secure algorithms).
Assuming you're a C-programmer, read the libsodium docs first. https://download.libsodium.org/doc/public-key_cryptography/s...
If you're using higher level language, use a library that provides bindings for it https://download.libsodium.org/doc/bindings_for_other_langua...
By using libsodium, you're not rolling your own crypto. Rolling your own crypto would mean
-trying to find new one way functions for public key crypto -trying to implement RSA from textbook -trying to implement RSA-OAEP from papers, RFCs, books etc.
Using a library is not anywhere near those. There are other ways to fail cryptography too, from not doing public key authentication, to storing private keys in insecure places.
So it's highly recommended you take time to read a book on the topic. The best modern book currently availalbe is https://www.amazon.com/Serious-Cryptography-Practical-Introd...
That's debatable. Libsodium does not have a proper authenticated key exchange. The key exchange does the job somewhat, but it has worse security properties than a properly crafted interactive protocol.
Problem is, designing your own key exchange protocol is more delicate than most construction. I know, I designed my own, and made several serious mistakes in the process (one of which voided an important security property).
Granted, rolling your own constructions is generally less error prone than rolling your own primitive. But it still shouldn't be done without at least having followed and fully understood an introductory course in cryptography (I recommend https://www.crypto101.io/). I mean, I did quite a bit more than that, and I still don't fully trust myself.
There are still some dangerous things you can do (e.g. mismanage keys, reuse nonces).
I wrote a library called Halite for PHP developers that wraps libsodium and makes it even harder to misuse. My philosophy was, "You shouldn't even need to know what a nonce is to use it securely."
https://github.com/paragonie/halite
From elsewhere in the thread, PyNaCl takes a similar approach. So how dangerous "just using libsodium" is, with respect to the "don't roll your own crypto" guidance, depends a little bit on which binding you're using.
Also, a lot of tasks might require a specific protocol (PAKEs, VPN protocols, searchable encryption, etc.) that libsodium isn't suitable for.
I wish I were a little better at SEO so average nerds would have an easy time finding it.
My only SEO advice is patience. Your articles are great, people will link to it increasingly often.
That said, why the sole PHP focus? The starting point you just linked to is pretty much independent from PHP, and there's libsodium bindings in plenty languages. If your goal is simply to make good crypto easier to do for "normal" developers then the PHP association may do more harm than good (particularly because PHP is not very hip right now)
I'm going to need to update it (Argon2id is now the default), so I might generalize the code (or make a tab system to switch between examples).
I authored Crypto 101. One of my cofounders co-authored Cryptopals and founded the cryptographic practice at Matasano (as well as co-founding Matasano itself ;)). So for cryptographic engineering, I think the answer is "historically oral, and increasingly written, tradition"?
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.
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/
[1] http://www.openbsd.org/papers/bsdcan-signify.html
[2] https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-08
[3] https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt?...
[4] https://www.apple.com/business/docs/iOS_Security_Guide.pdf
[5] https://www.chromestatus.com/feature/5682529109540864
[6] https://www.microsoft.com/en-us/research/wp-content/uploads/...
And even then if you found good solid well supported security advice from reputable sources but they are 10 years old... You are still insecure.
Therefore modern up to date information from reputable sources is the only true way to stay secure. Its a running battle not a static one.
I feel you have assumed I meant something entirely different.
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/) 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
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/
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.
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.
> 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.
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. 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.
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.
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/
[1] https://paragonie.com/blog/2017/06/libsodium-quick-reference...