30th of March 2021
I was recently asked via email about some good sources for learning about cryptography and thought I should share a padded out version of my reply here. I hope this is useful.
Firstly, you don't need a computer science or maths degree to learn about cryptography. Those types of qualifications will significantly speed up the learning process when in comes to more advanced topics and are required for very advanced topics, but in many cases, the maths behind cryptography is not necessarily important to learn. If you are a developer, then you should not be focused on the maths. You do not need to learn about mathematical proofs or theoretical cryptography. Ignore people telling you otherwise because they are speaking rubbish.
I recommend Real-World Cryptography as a first read because it's beginner friendly and doesn't require a mathematical background. It explains a lot of the core concepts and discusses modern algorithms like ChaCha20-Poly1350 and AES-GCM in enough detail. It certainly doesn't cover everything, but that's good because you shouldn't jump straight into the deep end anyway. However, it contains a lot of spelling and grammar mistakes at the moment since it's still being edited at the time of writing this.
Another less mathematical book is Everyday Cryptography. This is a much larger book covering more topics that has very positive reviews. It's meant to offer a solid introduction to cryptography without a bunch of maths.
Some other highly regarded books include Cryptography Engineering and Serious Cryptography. I believe these contain noticeably more mathematical notation than the first two books I've mentioned, so they're probably best for more advanced readers.
There's also a free ebook called Crypto 101, which is recommended by the Monocypher maintainer. This is meant to be an introductory course for programmers of all ages and skill levels, but it looks like familiarity with cryptographic notation is required. It's also still being written and contains some missing sections. Therefore, I don't recommend it over the books I've listed above.
Finally, Crypto Dictionary offers a light read and will help you learn some fun facts. However, some of the definitions aren't really definitions, some terms/algorithms have been skipped over, and it intentionally doesn't contain much detail. This should not be your first read.
The course I've seen recommended everywhere is Cryptography I by Dan Boneh from Stanford University, but I would strongly advise against taking this course if you're a beginner or someone who doesn't have a maths background. It's also very theoretical rather than applied, which is a shame because applied cryptography is far more important for most people.
Another Coursera course that sounds less mathematical is Introduction to Applied Cryptography from the University of Colorado. Then if you want to improve your general computer science knowledge, you should check out the Open Source Computer Science Degree list.
You can ask questions related to cryptography on Cryptography Stack Exchange and r/crypto. However, I would use these as a last resort because some responses are guaranteed to be outright wrong and many answers on Cryptography Stack Exchange are mathetical in nature rather than summarised in layman's terms. Books are a much safer bet when it comes to locating reliable information.
In terms of cryptographic libraries, stick to libsodium, Monocypher, or Tink and read the relevant documentation before coding anything. Even if your programming language already has a great library like Go does, the three libraries I just mentioned are likely easier and safer to use.
In terms of practice, Crytopals is a good way to work through some increasingly difficult cryptography challenges in a programming language of your choice. However, I'd also recommend just trying to program your own private file encryption program or demos of how to do password hashing, key exchange, etc using one of the cryptographic libraries I discussed above.
You can then review your code to ensure that you haven't made any common implementation mistakes like reusing nonces, using an insecure source of randomness, not comparing authentication tags in constant time, etc. Learning by doing works well, and if there's anything you're unsure of, then you should search it up and ask someone else as a last resort.
Finally, once you become more knowledgeable, you could try writing some existing algorithms (not creating your own - don't do this because even the most fully qualified cryptographers design insecure algorithms). HKDF and HMAC are a good place to start.
However, this sort of thing is very easy to cock up, and you should not implement anything complicated (e.g. Elligator) until you are very experienced in the subject. If you do this, then you should always review your code multiple times against the specification and test your code against the provided test vectors at the end of the specification. Never assume your code is secure.