[] Cryptographic library used in Devolutions products. It is made to be fast, easy to use and misuse-resistant.
- Overview
- Ciphertext Module
- Key Module
- PasswordHash Module
- SecretSharing Module
- Signature Module
- Utils Module
The library is split into multiple modules, which are explained below.
This module contains everything related to encryption. You can use it to encrypt and decrypt data using either a shared key of a keypair.
using Devolutions.Cryptography;
byte[] key = Managed.GenerateKey(32);
byte[] data = Utils.StringToUtf8ByteArray("somesecretdata");
byte[] encrypted_data = Managed.Encrypt(data, key, CipherVersion.Latest);
byte[] decrypted_data = Managed.Decrypt(encrypted_data, key);
Here, you will need a PublicKey
to encrypt data and the corresponding
PrivateKey
to decrypt it. You can generate them by using GenerateKeyPair
or DeriveKeyPair
in the Key module.
using Devolutions.Cryptography;
KeyPair keypair = Managed.GenerateKeyPair();
byte[] data = Utils.StringToUtf8ByteArray("somesecretdata");
byte[] encrypted_data = Managed.EncryptAsymmetric(data, keypair.PublicKey, CipherVersion.Latest);
byte[] decrypted_data = Managed.DecryptAsymmetric(data, keypair.PrivateKey);
You have two ways to generate a KeyPair
: Using GenerateKeyPair
will generate a random one, using DeriveKeyPair
will derive one from another password or key along with derivation parameters(including salt). Except in specific circumstances, you should use GenerateKeyPair
.
Asymmetric keys have two uses. They can be used to encrypt and decrypt data and to perform a key exchange.
using Devolutions.Cryptography;
KeyPair keypair = Managed.GenerateKeyPair();
using Devolutions.Cryptography;
Argon2Parameters parameters = Managed.GetDefaultArgon2Parameters();
KeyPair keypair = Managed.DeriveKeyPair(Utils.StringToUtf8ByteArray("thisisapassword"), parameters);
The goal of using a key exchange is to get a shared secret key between two parties without making it possible for users listening on the conversation to guess that shared key.
- Alice and Bob each generate a
KeyPair
. - Alice and Bob exchange their
PublicKey
. - Alice mixes her
PrivateKey
with Bob'sPublicKey
. This gives her the shared key. - Bob mixes his
PrivateKey
with Alice'sPublicKey
. This gives him the shared key. - Both Bob and Alice have the same shared key, which they can use for symmetric encryption for further communications.
using Devolutions.Cryptography;
KeyPair bob_keypair = Managed.GenerateKeyPair();
KeyPair alice_keypair = Managed.GenerateKeyPair();
byte[] bob_shared = Managed.MixKeyExchange(bob_keypair.PrivateKey, alice_keypair.PublicKey);
byte[] alice_shared = Managed.MixKeyExchange(alice_keypair.PrivateKey, bob_keypair.PublicKey);
You can use this module to hash a password and validate it afterward. This is the recommended way to verify a user password on login.
using Devolutions.Cryptography;
byte[] password = Utils.StringToUtf8ByteArray("somesuperstrongpa$$w0rd!");
byte[] hashed_password = Managed.HashPassword(password, 10000);
This module is used to generate a key that is split in multiple Share
and that requires a specific amount of them to regenerate the key.
You can think of it as a "Break The Glass" scenario. You can for example
generate a key, encrypt your data and then require 3 out of the 5 administrators
to decrypt the data. That data could also be an API key or password of a super
admin account.
using Devolutions.Cryptography;
using System.Linq;
// You want a key of 32 bytes, split between 5 people, and a
// minimum of 3 of these shares to regenerate the key.
byte[][] shares = Managed.GenerateSharedKey(5, 3, 32);
byte[] key = Managed.JoinShares(shares.Skip(2).ToArray());
This module is used to sign data using a keypair to certify its authenticity.
using Devolutions.Cryptography;
using System.Linq;
SigningKeyPair keypair = Managed.GenerateSigningKeyPair();
byte[] dataToSign = System.Text.Encoding.UTF8.GetBytes("some data");
byte[] signature = Managed.Sign(dataToSign, keypair);
byte[] dataToVerify = System.Text.Encoding.UTF8.GetBytes("some data");
bool valid = Managed.VerifySignature(dataToVerify, keypair.GetPublicKey(), signature);
These are a bunch of functions that can be useful when dealing with the library.
This is a method used to generate a random key. In almost all case, the keySize
parameter should be 32.
using Devolutions.Cryptography;
byte[] key = Managed.GenerateKey(32);
This is a method used to generate a key from a password or another key. Useful for password-dependant cryptography. Salt should be a random 16 bytes array if possible and iterations should be 10000 or configurable by the user.
using Devolutions.Cryptography;
byte[] key = Utils.StringToUtf8ByteArray("this is a secret password");
byte[] salt = Managed.GenerateKey(16);
uint iterations = 10000;
uint length = 32;
byte[] new_key = Managed.DeriveKey(key, salt, iterations, length);
As of the current version:
- Symmetric cryptography uses XChaCha20Poly1305
- Asymmetric cryptography uses Curve25519
- Asymmetric encryption uses ECIES
- Key exchange uses x25519, or ECDH over Curve25519
- Password Hashing uses PBKDF2-HMAC-SHA2-256
- Secret Sharing uses Shamir Secret sharing over GF256