1 module dcrypto.key; 2 3 import std.random; 4 import std..string; 5 6 import deimos.openssl.evp; 7 8 import dcrypto.dcrypto; 9 10 /// Basic struct for for storing a key. Includes a key, an iv and a salt. 11 struct Key { 12 ubyte[] key, iv, salt; 13 14 /// Allocates memory for the requested key lengths. By default they are set to the maximum values per the openssl library. 15 void setSize(int keyLength = EVP_MAX_KEY_LENGTH, int ivLength = EVP_MAX_IV_LENGTH) { 16 key = new ubyte[](keyLength); 17 iv = new ubyte[](ivLength); 18 } 19 20 /// Creates a random salt of the specified size. 21 ref Key randomizeSalt(size_t size = 8) { 22 salt = new ubyte[](size); 23 fillRandom!ubyte(salt); 24 return this; 25 } 26 27 /// Creates a random key and iv of the specified size 28 ref Key randomize(int keyLength = EVP_MAX_KEY_LENGTH, int ivLength = EVP_MAX_IV_LENGTH) { 29 setSize(keyLength, ivLength); 30 fillRandom!ubyte(key); 31 fillRandom!ubyte(iv); 32 return this; 33 } 34 35 } 36 37 /// Build and return a key based on secret data with a random salt generated 38 Key keyFromSecret(string data, int rounds = 200, int keyLength = EVP_MAX_KEY_LENGTH, int ivLength = EVP_MAX_IV_LENGTH) { 39 Key returnKey; 40 41 returnKey.randomizeSalt(); 42 returnKey.setSize(keyLength, ivLength); 43 44 auto d = representation(data); 45 EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), returnKey.salt.ptr, d.ptr, returnKey.key.sizeof, rounds, returnKey.key.ptr, returnKey.iv.ptr); 46 47 return returnKey; 48 } 49 50 /// Build and return a key based on secret data using the specified salt 51 Key keyFromSecret(string data, string salt, int rounds = 200, int keyLength = EVP_MAX_KEY_LENGTH, int ivLength = EVP_MAX_IV_LENGTH) { 52 Key returnKey; 53 54 returnKey.salt = representation(salt).dup; 55 returnKey.setSize(keyLength, ivLength); 56 57 auto d = representation(data); 58 EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), returnKey.salt.ptr, d.ptr, returnKey.key.sizeof, rounds, returnKey.key.ptr, returnKey.iv.ptr); 59 60 return returnKey; 61 }