While looking for end-to-end encryption for my app users, I stumbled upon NaCl and libsodium. I am unsure from a security perspective which of these implementations I should use for my cross-platform app.

Are there big differences in the level of security they offer?

  • $\begingroup$ Welcome to Cryptography. I'm not sure that this question fits into our scope. For an end to end encryption use Signal Protocole. It is open source. $\endgroup$ – kelalaka Mar 10 at 22:07
  • $\begingroup$ libsodium has everything that NaCl has because it was based on that project. I think that libsodium is used more. libsodium's additions are useful. $\endgroup$ – Future Security Mar 11 at 1:43

(I don't have an opinion on NaCl as I've never used it. My understanding is that Libsodium uses NaCl in parts, and/ or re-implements it in others.)

As far as security goes, they should both be as equally secure. As far as I know they are both opinionated in that they don't provide you with an option to use less-secure techniques. In virtually every cryptographic primitive you seek, you will only find one or two more recent and more secure (ie. best-practice). This link elaborates on some of the design decisions:


Here is a good resource on Libsodium from Paragon - if you're using PHP you'll no doubt wind up here as the standard doco is a whole bunch of 'todo':


You don't specify a language, however, I have used Libsodium successfully across numerous Linux kernels, in PHP, Python (pysodium), Javascript, Windows 8.1+, and Android 7+ (via Termux). I have also interchanged certain primitives from pysodium with another Python library called cryptography.io (which relies upon OpenSSL).

One thing I like is the way the library provides two interfaces in many circumstances: a 'generically named' function, and an explicitly named one. For example, you can call crypto_aead_xchacha20poly1305_ietf_encrypt which explicitly defines the cipher in use, or, you can call crypto_secretbox and allow your cryptography to be 'upgraded' in the future if a newer version emerges that modifies default behaviour.

One shortcoming I have discovered so far, at least for pysodium's use of this library, is that the api exposure for Argon2id doesn't support associated data, whereas the actual algorithm code-base in the library does:

  1. https://github.com/jedisct1/libsodium/blob/927dfe8e2eaa86160d3ba12a7e3258fbc322909c/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c#L136

  2. https://github.com/jedisct1/libsodium/blob/a97ab7085fcda73f4fc7dead1a499025ceda9ecc/src/libsodium/crypto_pwhash/argon2/argon2-core.c#L470

In practice, this wasn't an issue, as I just hashed the associated data with the password - however, this might be a problem in some implementations, especially if you're producing a PBKDF in parallel with another library's so you can exchange data (in an end-to-end protocol for example). If you're using Python, you can use the argon2-cffi implementation in most circumstances.

The lack of AES-ECB and AES-CBC ciphers has prevented me from using Libsodium exclusively on one MySQL-integration project, however, it was no drama to use cryptography.io as a bridge in that circumstance. That is how I started looking at compatibility between Libsodium and OpenSSL (via pysodium and cryptography.io).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.