devolutions-crypto 0.9.2

An abstraction layer for the cryptography used by Devolutions
Documentation
# devolutions-crypto
[![Build Status](https://github.com/Devolutions/devolutions-crypto/actions/workflows/ci.yml/badge.svg)]
Cryptographic library used in Devolutions products. It is made to be fast, easy to use and misuse-resistant.

# Usage
* [Overview]#overview
* [Ciphertext Module]#ciphertext
    * [Symmetric Encryption]#symmetric
    * [Asymmetric Encryption]#asymmetric
* [Key Module]#key
    * [Key Generation/Derivation]#generationderivation
    * [Key Exchange]#key-exchange
* [PasswordHash Module]#passwordhash
* [SecretSharing Module]#secretsharing
* [Signature Module]#signature
    * [Generating Key Pairs]#generating-key-pairs
    * [Signing data]#signing-data
    * [Signature Verification]#verifying-the-signature
* [Utils Module]#utils
    * [Key Generation]#key-generation
    * [Key Derivation]#key-derivation
    

## Overview

The library is split into multiple modules, which are explained below.

## Ciphertext

This module contains everything related to encryption. You can use it to encrypt and decrypt data using either a shared key of a keypair.

### Symmetric

```C#
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);
```

### Asymmetric
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](#key).

```C#
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);
```

### Generation/Derivation

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](##asymmetric) and to perform a [key exchange](#key-exchange).

#### `Generate Key Pair`
```C#
using Devolutions.Cryptography;

KeyPair keypair = Managed.GenerateKeyPair();
```

#### `DeriveKeyPair`
```C#
using Devolutions.Cryptography;

Argon2Parameters parameters = Managed.GetDefaultArgon2Parameters();

KeyPair keypair = Managed.DeriveKeyPair(Utils.StringToUtf8ByteArray("thisisapassword"), parameters);
```

### Key Exchange

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.
1. Alice and Bob each generate a `KeyPair`.
2. Alice and Bob exchange their `PublicKey`.
3. Alice mixes her `PrivateKey` with Bob's `PublicKey`. This gives her the shared key.
4. Bob mixes his `PrivateKey` with Alice's `PublicKey`. This gives him the shared key.
5. Both Bob and Alice have the same shared key, which they can use for symmetric encryption for further communications.

```C#
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);
```

## PasswordHash
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.

```C#
using Devolutions.Cryptography;

byte[] password = Utils.StringToUtf8ByteArray("somesuperstrongpa$$w0rd!");

byte[] hashed_password = Managed.HashPassword(password, 10000);
```

## SecretSharing
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.

```c#
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());
```

## Signature
This module is used to sign data using a keypair to certify its authenticity. 

###  Generating Key Pairs
```c#
using Devolutions.Cryptography;
using System.Linq;

SigningKeyPair keypair = Managed.GenerateSigningKeyPair();
```
### Signing Data
```c#
byte[] dataToSign = System.Text.Encoding.UTF8.GetBytes("some data");

byte[] signature = Managed.Sign(dataToSign, keypair);
```

### Verifying the signature
```c#
byte[] dataToVerify = System.Text.Encoding.UTF8.GetBytes("some data");

bool valid = Managed.VerifySignature(dataToVerify, keypair.GetPublicKey(), signature);
```


## Utils

These are a bunch of functions that can
be useful when dealing with the library.

### Key Generation

This is a method used to generate a random key. In almost all case, the `keySize` parameter should be 32.

```C#
using Devolutions.Cryptography;

byte[] key = Managed.GenerateKey(32);
```

### Key Derivation

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.

```C#
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);
```

# Underlying algorithms
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