libsodium-net, or better said, libsodium for .NET, is a C# wrapper around libsodium. For those that don't know, libsodium is a portable implementation of Daniel Bernstein's fantastic NaCl library. If you aren't familiar with NaCl, I highly suggest that you look into libsodium and NaCl before using this library.
Want to support development? Consider donating via Bitcoin to 14jumFDmuVkLiAt4TgyKt17SWHtPRbkcLr
- all donations, no matter how small are appreciated.
NaCl is a great library in that its designed has made the right choices on what to implement and how - something most developers don't know how to do. So by using it (or a wrapper), many of those details are abstracted away where you don't need to worry about them. NaCl itself is less than portable C, only targeted for *nix systems; libsodium solves this by making it portable and making a few minor changes to better suite being distributed as a compiled binary.
Crypto is hard - much harder than your average developer understands. This effort was started to make these tools readily available to the .NET community in hopes they will be used to further the goals of defending personal privacy and security.
Windows: For Windows, the libsodium
library is included in the release packages. Or just use the NuGet version which has everything you need.
OSX: For OSX, libsodium-net
can easily be built in Xamarin Studio, and libsodium
can be installed easily via brew
:
brew install libsodium --universal
Linux: As with OSX, building with Xamarin Studio is simple, or there's always the option of using xbuild
:
xbuild libsodium-net.sln
For libsodium
, many package managers provide older versions, so it's recommended to build the latest version from source. Thankfully, this is a fairly painless process. See the travis-build-libsodium.sh file or the libsodium
README file for details.
Other: Support for other Mono supported platforms hasn't been determined. It may or may not work.
Note: For all platforms, it's critical that libsodium
be compiled for the architecture that the process is running under. If they don't match, you can expect to see errors. If your process is x86/i386, you can't use a copy of libsodium
compiled for x64.
The following methods have been implemented and have at least basic unit tests in place to ensure they are producing the expected output. (Listed in no particular order)
Sodium.PublicKeyAuth.GenerateKeyPair()
- Generates a public/private Ed25519 key pair based on a random seed. The public key is 32 bytes, the private key is 64 bytes.
Sodium.PublicKeyAuth.GenerateKeyPair()
- Generates a public/private Ed25519 key pair based on the provided seed to allow deterministic key generation. The public key is 32 bytes, the private key is 64 bytes, seed must be 32 bytes.
Sodium.PublicKeyAuth.Sign()
- Signs a message with Ed25519, based on the supplied 64 byte private key.
Sodium.PublicKeyAuth.Verify()
- Verifies the signature and returns the clear-text message using Ed25519 and the supplied 32-byte public key.
Sodium.PublicKeyAuth.SignDetached()
- Similar to crypto_sign
, except returns a Signature
without the message.
Sodium.PublicKeyAuth.VerifyDetached()
- Verifies the signature and returns true
or false
. Throws a CryptographicException
if verification fails.
Sodium.PublicKeyAuth.ConvertEd25519PublicKeyToCurve25519PublicKey()
- Converts a Ed25519 public key, to a Curve25519 public key.
Sodium.PublicKeyAuth.ConvertEd25519SecretKeyToCurve25519SecretKey()
- Converts a Ed25519 private key, to a Curve25519 private key.
Sodium.PublicKeyBox.GenerateKeyPair()
- Generates a public/private Curve25519-XSalsa20-Poly1305 key pair based on a random seed. The public key is 32 bytes, the private key is 32 bytes.
Sodium.PublicKeyBox.Create()
- Encrypts a message using the sender's private key, and the recipient's public key. Both keys are 32 bytes. Encryption / signing is performed via Curve25519-XSalsa20-Poly1305.
Sodium.PublicKeyBox.Open()
- Decrypts and verifies the sender's signature using the recipient's private key and the sender's public key. Both keys are 32 bytes. Throws a CryptographicException
if verification fails.
Sodium.PublicKeyBox.CreateDetached()
- Similar to crypto_box
, except returns a DedatchedBox
object, with the cipher text and MAC separated.
Sodium.PublicKeyBox.OpenDetached()
- Similar to crypto_box_open
, except dealing with a detached MAC. See crypto_box_detached
.
Sodium.SecretBox.Create()
- This method encrypts and authenticates a message. This is currently implemented via XSalsa20 and Poly1305.
Details:
- Key length: 32 bytes
- Nonce length: 24 bytes
Note: As in any crypto system, it's important to avoid reusing a nonce, so the nonce should either be randomly generated or consist of a non-repeatable message ID. To minimize risks, my recommendation is to randomly generate the nonce.
Sodium.SecretBox.Open()
- This method retrieves the message encrypted via SecretBox.Create()
. To decrypt and authenticate the data, you pass the key, nonce, and cipher text; if there is an issue decrypting the message, you will receive a generic CryptographicException
- the exact reason for the failure isn't provided.
Sodium.SecretBox.CreateDetached()
- Similar to crypto_secretbox
, except returns a DedatchedBox
object, with the cipher text and MAC separated.
Sodium.SecretBox.OpenDetached()
- Similar to crypto_secretbox_open
, except dealing with a detached MAC. See crypto_secretbox_detached
.
Sodium.OneTimeAuth.Sign()
- Provides messages authentication via Poly1305. The method takes a messages (as UTF-8 string or byte array), a 32 byte key (that must be used only once), and returns a 16 bytes signature.
For this to be secure, it's required that the signing key only be used once.
Sodium.OneTimeAuth.Verify()
- This verifies a signature generated via crypto_onetimeauth
. To do so, it requires the original message, the 16 byte signature, and the 32 byte key.
Sodium.SecretKeyAuth.Sign()
- Provides messages authentication via HMAC-SHA512-256. The method takes a messages (as UTF-8 string or byte array), a 32 byte key, and returns a 32 bytes signature.
Sodium.SecretKeyAuth.Verify()
- This verifies a signature generated via crypto_auth
. To do so, it requires the original message, the 32 byte signature, and the 32 byte key.
Sodium.SecretKeyAuth.SignHmacSha256()
- Provides messages authentication via HMAC-256. The method takes a messages (as UTF-8 string or byte array), a 32 byte key, and returns a 32 bytes signature.
Sodium.SecretKeyAuth.VerifyHmacSha256()
- This verifies a signature generated via crypto_auth_hmacsha256
. To do so, it requires the original message, the 32 byte signature, and the 32 byte key.
Sodium.SecretKeyAuth.SignHmacSha512()
- Provides messages authentication via HMAC-512. The method takes a messages (as UTF-8 string or byte array), a 32 byte key, and returns a 64 bytes signature.
Sodium.SecretKeyAuth.VerifyHmacSha512()
- This verifies a signature generated via crypto_auth_hmacsha512
. To do so, it requires the original message, the 64 byte signature, and the 32 byte key.
Sodium.SecretAead.Encrypt()
- Encrypts a message with an authentication tag and additional data.
Sodium.SecretAead.Decrypt()
- Decrypts a cipher with an authentication tag and additional data.
Sodium.StreamEncryption.GenerateNonce()
- Returns a 24 random byte nonce.
Sodium.StreamEncryption.Encrypt()
- Encrypts a message via XSalsa20 using a 32 byte key and a 24 byte nonce. As always, it's critical that the nonce never be reused. This provides encryption only, not authentication.
Sodium.StreamEncryption.Decrypt()
- Decrypts messages via XSalsa20.
Sodium.StreamEncryption.GenerateNonceChaCha20()
- Returns a 8 random byte nonce.
Sodium.StreamEncryption.EncryptChaCha20()
- Encrypts a message via ChaCha20 using a 32 byte key and a 8 byte nonce. This provides encryption only, not authentication.
Sodium.StreamEncryption.DecryptChaCha20()
- Decrypts messages via ChaCha20.
The nonce is 64 bits long. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce every time a new stream is required.
Sodium.CryptoHash.Hash()
- This hashes a message (UTF-8 encoded string
or byte[]
) using the default algorithm, currently SHA-512. A byte array is returned.
The Sodium.CryptoHash
class also includes the following methods:
Sha512()
- Compute a SHA-512 hash (for compatibility if the default algorithm is ever changed). (crypto_hash_sha512
)Sha256()
- Compute a SHA-256 hash. (crypto_hash_sha256
)
Sodium.GenericHash.Hash()
- This is a multi-purpose fast hash, that has variable output size and an optional key. As with the CryptoHash
methods, the input can be a UTF-8 encoded string, or a byte array, and a byte array is returned.
This is the most flexible hashing option; and the one I would recommend the most.
This is currently based on BLAKE2b, and has the following properties:
- Variable output from 16 to 64 bytes.
- Optional keyed mode, accepting a key from 16 to 64 bytes.
Note: Only libsodium's simplified interface is currently supported; the streaming interface is not implemented at this time.
Sodium.ShortHash.Hash()
- Short, high-speed hashing, currently implanted via SipHash-2-4 and produces an 8 byte hash.
Sodium.GenericHash.HashSaltPersonal()
- Hash with salt, personal and optional key.
Sodium.PasswordHash.ScryptHashString()
- Returns the hash is a string format, which includes the generated salt.
Sodium.PasswordHash.ScryptHashStringVerify()
- Verifies that a hash generated with ScryptHashString
matches the supplied password.
Sodium.PasswordHash.ScryptHashBinary()
- Derives a secret key of any size from a password and a salt. There exists an overloaded version with some predefined limits for an easy usage.
Sodium.SodiumCore.SodiumVersionString()
- This returns the version string on the libsodium
library in use. Note, this is not the version of libsodium-net.
Sodium.SodiumCore.GetRandomBytes()
- Gets a number of random bytes, suitable for use as a key or nonce. In classes where appropriate, there are GenerateKey()
and/or GenerateNonce()
functions that return a byte array of the correct size.
Sodium.ScalarMult.Mult()
- Diffie-Hellman (function computes a secret shared by the two keys)
Sodium.ScalarMult.Base()
- Diffie-Hellman (computes the public key from the given secret key)
Sodium.Utilities.HexToBinary()
- This method converts a hex-encoded string (lower-case, upper-case or with some extra chars like: Hyphen, Colon and Space) to a byte array.
Sodium.Utilities.BinaryToHex()
- This method takes a byte array, and produces a lower-case hex-encoded string.
There are a small number of additional methods that extended or simplify the usage of this library.
Sodium.Utilities.BinaryToHex()
- This overload takes a byte array, and produces a lower-case or upper-case hex-encoded string, it also can add some extra chars (Hyphen, Colon and Space) to generate a human readable format.
Note: This overload doesn't use the sodium_bin2hex implementation.
This library can be built in Visual Studio 2010, Xamarin Studio (MonoDevelop 3.x supported), and targets .NET 4.0; it is compiled against libsodium v1.0.0.
On OSX & Linux, your copy of libsodium
must be compiled for the same architecture as your copy of Mono. If you are running a 32bit process, your copy of libsodium
must be 32bit as well.
Any method that takes a String, has an overload that accepts a byte array; Strings are assumed to be UTF8; if this is not the case, please convert it to bytes yourself and use the overloads that accept byte arrays.
Starting with version 0.4.0, all files are signed via a Certum.pl Code Signing certificate. The files are signed under the name Open Source Developer, Adam Caudill
- this can be used to ensure that the files haven't been altered.
NaCl has been released to the public domain to avoid copyright issues. libsodium is subject to the ISC license, and this software is subject to the MIT license (see LICENSE).