Cryptographic Libraries
「 Overview 」
Recommended 「 In Order 」
Libsodium
- Modern
- Extremely fast
- Easy to use
- Well documented
Audited library that covers all common use cases besides implementing TLS.
However, it’s much bigger than Monocypher, which makes it
harder to audit and thus not suitable for constrained environments.
It also requires the Visual C++ Redistributable to work on Windows.
Monocypher
- Modern
- Easy to use
- Well documented
Audited library, but it’s about half the speed of Libsodium on desktops / servers.
Has no misuse resistant functions Libsodium’s secretstream() and secretbox() .
Only supports Argon2i for password hashing, allowing for insecure parameters
(please see the Password Hashing/Password-Based Key Derivation Notes section)
Offers no
- Memory Locking
- Random Number Generation
- Base64 / Hex Encoding, Padding, ..
However, it’s compatible with Libsodium whilst being
- Fast
- Small
- Portable
making it useful for constrained environments like microcontrollers.
Tink
A misuse resistant library that prevents common pitfalls, like nonce reuse.
However, it doesn’t support hashing or password hashing, it’s not available
in as many programming languages as Libsodium and Monocypher, and it
provides access to some algorithms that you shouldn’t use.
LibHydrogen
- Lightweight
- Easy to use
- Hard to misuse
- Well documented
- Suitable for most environments
The downsides are that it’s not compatible with
Libsodium whilst also running slower than Monocypher.
However, it has some advantages over Monocypher like support
for random number generation, even on Arduino boards,
and easy access to key exchange patterns, among other things.
Avoid 「 In Order 」
Random Github Libraries
➜ With 0 stars
Assuming it’s not been written by an experienced professional and isn’t a
Libsodium / Monocypher binding to another programming language,
you should probably not use it.
Generally try to stay away from unpopular / unaudited libraries, as they
are much more likely to be significantly slower and suffer from
vulnerabilities than the more popular, audited libraries.
Also, note that even experienced professionals make mistakes.
OpenSSL
- Difficult to use / to use correctly
- The documentation is a mess
- Many vulnerabilities have been found over the years
- Offers access to algorithms that you shouldn’t use
These issues have led to OpenSSL forks and new, non-forked libraries
that aim to be better alternatives in case you need to implement TLS.
The Library In Your Programming Language
Most languages provide access to old algorithms like MD5 and SHA1,
that shouldn’t be used anymore, instead of newer ones such as
BLAKE2, BLAKE3 and SHA3, which can lead to poor algorithm choices.
Furthermore
- The APIs are typically easy to misuse
- The documentation may fail to mention important security related information
- And the implementations will likely be slower than Libsodium.
〔 Bouncy Castle 〕〔 CryptoJS 〕
And other popular libraries
These again often provide or rely on dated algorithms and typically have bad documentation.
For instance, CryptoJS uses an insecure KDF called EVP_BytesToKey()
in OpenSSL when you
pass a string password to AES.encrypt()
, and BouncyCastle has no C# documentation.
However, this recommendation is too broad. Since there are some libraries that I haven’t
mentioned that are worth using, like PASETO, you can go with this rule of thumb:
If it doesn't include several of the algorithms I recommend, then it's probably bad
Just do your research and assess the quality of the documentation.
NaCl
- Unmaintained
- Less modern
- More confusing version of Libsodium and Monocypher
For example, crypto_sign()
for digital signatures has been experimental for several years.
It also doesn’t have password hashing support and is supposedly difficult to install / package.
TweetNaCl
- Unmaintained
- Slower than Monocypher
- Doesn’t offer access to newer algorithms
- Doesn’t have password hashing
- Doesn’t zero out buffers
Notes
- If the library you’re currently using/planning to use doesn’t support several of the
algorithms I’m recommending, then it’s time to upgrade and take advantage of the
improved security and performance benefits available to you if you switch.
- Please read the documentation
Don’t immediately jump into coding something because that’s how mistakes are made.
Good libraries have high quality documentation that will
explain potential security pitfalls and how to avoid them.
- Some libraries release unauthenticated plaintext when using AEADs
For example, OpenSSL and BouncyCastle apparently do.
Firstly, don’t use these libraries for this reason and the reasons I’ve already listed.
Secondly, never do anything with unauthenticated plaintext, ignore it to be safe.
- Older does not mean better
You can argue that older algorithms are more battle tested and therefore proven to be
a safe choice, but the reality is that most modern algorithms, like ChaCha20, BLAKE2,
and Argon2, have been properly analyzed at this point and shown to offer security and
performance benefits over their older counterparts.
Therefore, it doesn’t make sense to stick to this overly cautious mindset of
avoiding newer algorithms, except for algorithms that are still candidates
in a competition (e.g. new post-quantum algorithms), which do need
further analysis to be considered safe.
- You should prioritize speed
This can make a noticeable difference for the user.
For example, a C# Argon2 library is going to significantly slower than Argon2
in Libsodium, meaning unnecessary and unwanted extra delay during key derivation.
Libsodium is the go-to for speed on desktops / servers, and Monocypher
is the go-to for constrained environments (e.g. microcontrollers).