-
Notifications
You must be signed in to change notification settings - Fork 172
Crypto API
OpenDHT provides a simple, easy to use C++ cryptographic API built on top of GnuTLS.
The crypto API is exposed in the dht::crypto
C++ namespace.
crypto::PrivateKey
represents an RSA private key.
Constructor allows to import an existing PEM or DER encoded private key:
PrivateKey(const std::vector<uint8_t>& key, const std::string& password = {});
A new RSA key pair can be generated using PrivateKey::generate()
:
static PrivateKey PrivateKey::generate(unsigned key_length = 4096);
The corresponding public key can be obtained using getPublicKey()
:
PublicKey PrivateKey::getPublicKey() const;
A private key can sign data:
/** Returns the signature of 'data'. */
std::vector<uint8_t> PrivateKey::sign(const std::vector<uint8_t>& data) const;
A private key can decrypt data previously encrypted with the corresponding public key:
std::vector<uint8_t> PrivateKey::decrypt(const std::vector<uint8_t>& encrypted_data) const;
crypto::PublicKey
represents an RSA public key.
Constructor allows to import an existing PEM or DER encoded public key:
PublicKey(const std::vector<uint8_t>& pk);
A public key can encrypt data:
std::vector<uint8_t> PublicKey::encrypt(const std::vector<uint8_t>& data) const;
A public key can check data signed by the corresponding private key:
bool PublicKey::checkSignature(const std::vector<uint8_t>& data, const std::vector<uint8_t>& signature) const;
Example use of crypto::PrivateKey
and crypto::PublicKey
:
auto key = dht::crypto::PrivateKey::generate();
auto public_key = key.getPublicKey();
std::vector<uint8_t> data {5, 10};
std::vector<uint8_t> signature = key.sign(data);
// check signature
assert(public_key.checkSignature(data, signature));
// encrypt data
std::vector<uint8_t> encrypted = public_key.encrypt(data);
std::vector<uint8_t> decrypted = key.decrypt(encrypted);
assert(data == decrypted);
crypto::Certificate
represents an x509 certificate.
Constructors allows to import an existing PEM or DER encoded certificate:
Certificate(const uint8_t* dat, size_t dat_size);
Certificate(const std::vector<uint8_t>& crt);
A new certificate can be generated using generate()
:
static Certificate
Certificate::generate(const PrivateKey& key, const std::string& name, Identity ca = {});
OpenDHT provides 128, 192 or 256 bits AES-GCM encryption. Using a raw key of 16, 24 or 32 bytes:
std::vector<uint8_t> crypto::aesEncrypt(const std::vector<uint8_t>& data, const std::vector<uint8_t>& key);
std::vector<uint8_t> crypto::aesDecrypt(const std::vector<uint8_t>& encrypted_data, const std::vector<uint8_t>& key);
Using a text password. The password is stretched and a generated salt appended to the encrypted data.
std::vector<uint8_t> crypto::aesEncrypt(const std::vector<uint8_t>& data, const std::string& password);
std::vector<uint8_t> crypto::aesDecrypt(const std::vector<uint8_t>& encrypted_data, const std::string& password);
Key stretching is the process of making a text password more secure against a brute force attack by increasing the time it takes to test each possible key.
Key stretching in OpenDHT makes use of argon2i (mono-threaded, 65536 rounds, 64 MiB). If an empty salt is provided, the salt parameter is filled with a generated salt. The same salt and password must be used to get the same output. The salt can be transmitted in clear.
std::vector<uint8_t> crypto::stretchKey(const std::string& password, std::vector<uint8_t>& salt);