Created
November 8, 2018 18:20
-
-
Save maldevel/08d07c24c67bea36f0db2019232ffa38 to your computer and use it in GitHub Desktop.
Dexter AES 256 CBC mode encryption code snippet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://github.com/twelvesec/dexter | |
//GNU General Public License v3.0 | |
//@maldevel | |
//... | |
static bool derive_key_from_password(std::string password, HCRYPTKEY *key, HCRYPTPROV *hCryptProv) { | |
HCRYPTHASH hHash = 0; | |
bool success = true; | |
if (success && CryptAcquireContext(hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) == FALSE) { | |
success = false; | |
} | |
if (success && CryptCreateHash(*hCryptProv, CALG_SHA_256, 0, 0, &hHash) == FALSE) { | |
success = false; | |
} | |
if (success && CryptHashData(hHash, (BYTE*)password.c_str(), (DWORD)password.length(), 0) == FALSE) { | |
success = false; | |
} | |
if (success && CryptDeriveKey(*hCryptProv, CALG_AES_256, hHash, CRYPT_EXPORTABLE, key) == FALSE) { | |
success = false; | |
} | |
if (hHash) { | |
CryptDestroyHash(hHash); | |
hHash = 0; | |
} | |
return success; | |
} | |
std::string libcrypt::encrypt(std::string password, std::string plaintext) { | |
std::string ciphertext; | |
DWORD ciphersize = 0; | |
DWORD ciphertempsize = 0; | |
BYTE *cipher = 0; | |
BYTE *ivandcipher = 0; | |
DWORD ivandciphersize = 0; | |
HCRYPTKEY key = 0; | |
HCRYPTPROV hCryptProv = 0; | |
DWORD mode = CRYPT_MODE_CBC; | |
DWORD padding = PKCS5_PADDING; | |
DWORD blocksize = 0, blocksizelen = sizeof(DWORD); | |
BYTE *iv = 0; | |
bool success = true; | |
if (success && derive_key_from_password(password, &key, &hCryptProv) == false) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_MODE, (BYTE*)&mode, 0) == FALSE) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_PADDING, (BYTE*)&padding, 0) == FALSE) { | |
success = false; | |
} | |
if (success && CryptGetKeyParam(key, KP_BLOCKLEN, (BYTE*)&blocksize, &blocksizelen, 0) == FALSE) { | |
success = false; | |
} | |
blocksize /= 8; | |
if (success && (iv = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, blocksize * sizeof(BYTE))) == NULL) { | |
success = false; | |
} | |
if (success && CryptGenRandom(hCryptProv, blocksize, iv) == FALSE) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_IV, iv, 0) == FALSE) { | |
success = false; | |
} | |
ciphersize = (DWORD)plaintext.length(); | |
if (success && CryptEncrypt(key, 0, TRUE, 0, NULL, &ciphersize, 0) == FALSE) { | |
success = false; | |
} | |
if (success && (cipher = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ciphersize * sizeof(BYTE))) == NULL) { | |
success = false; | |
} | |
if (success && memcpy_s(cipher, ciphersize, plaintext.c_str(), plaintext.length()) != 0) { | |
success = false; | |
} | |
ciphertempsize = ciphersize; | |
ciphersize = (DWORD)plaintext.length(); | |
if (success && CryptEncrypt(key, 0, TRUE, 0, cipher, &ciphersize, ciphertempsize) == FALSE) { | |
success = false; | |
} | |
ivandciphersize = ciphersize + blocksize; | |
if (success && (ivandcipher = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ivandciphersize * sizeof(BYTE))) == NULL) { | |
success = false; | |
} | |
if (success && (memcpy_s(ivandcipher, ivandciphersize, iv, blocksize) != 0 || memcpy_s(ivandcipher + blocksize, ivandciphersize, cipher, ciphersize) != 0)) { | |
success = false; | |
} | |
if (success && (ciphertext = libencode::base64_encode(ivandcipher, ivandciphersize)) == "") { | |
success = false; | |
} | |
if (ivandcipher) { | |
HeapFree(GetProcessHeap(), 0, ivandcipher); | |
ivandcipher = NULL; | |
} | |
if (cipher) { | |
HeapFree(GetProcessHeap(), 0, cipher); | |
cipher = NULL; | |
} | |
if (iv) { | |
HeapFree(GetProcessHeap(), 0, iv); | |
iv = NULL; | |
} | |
if (key) { | |
CryptDestroyKey(key); | |
key = NULL; | |
} | |
if (hCryptProv) { | |
CryptReleaseContext(hCryptProv, 0); | |
hCryptProv = NULL; | |
} | |
return ciphertext; | |
} | |
std::string libcrypt::decrypt(std::string password, std::string ciphertext) { | |
std::string plaintext; | |
bool success = true; | |
HCRYPTKEY key = 0; | |
HCRYPTPROV hCryptProv = 0; | |
DWORD mode = CRYPT_MODE_CBC; | |
DWORD padding = PKCS5_PADDING; | |
DWORD blocksize = 0, blocksizelen = sizeof(DWORD); | |
BYTE *iv = 0; | |
BYTE *decoded = 0; | |
BYTE *ivandcipher = 0; | |
DWORD ivandciphersize = 0; | |
if (success && derive_key_from_password(password, &key, &hCryptProv) == false) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_MODE, (BYTE*)&mode, 0) == FALSE) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_PADDING, (BYTE*)&padding, 0) == FALSE) { | |
success = false; | |
} | |
if (success && CryptGetKeyParam(key, KP_BLOCKLEN, (BYTE*)&blocksize, &blocksizelen, 0) == FALSE) { | |
success = false; | |
} | |
blocksize /= 8; | |
if (success && (iv = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, blocksize * sizeof(BYTE))) == NULL) { | |
success = false; | |
} | |
if (success && (ivandciphersize = libencode::base64_decode(&decoded, ciphertext.c_str())) == 0) { | |
success = false; | |
} | |
ivandciphersize -= blocksize; | |
if (success && (ivandcipher = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ivandciphersize * sizeof(BYTE))) == NULL) { | |
success = false; | |
} | |
if (success && (memcpy_s(iv, blocksize, decoded, blocksize) != 0 || memcpy_s(ivandcipher, ivandciphersize, decoded + blocksize, ivandciphersize) != 0)) { | |
success = false; | |
} | |
if (success && CryptSetKeyParam(key, KP_IV, iv, 0) == FALSE) { | |
success = false; | |
} | |
if (CryptDecrypt(key, 0, TRUE, 0, ivandcipher, &ivandciphersize) == FALSE) { | |
success = false; | |
} | |
ivandcipher[ivandciphersize] = 0; | |
plaintext = std::string((char*)ivandcipher); | |
if (iv) { | |
HeapFree(GetProcessHeap(), 0, iv); | |
iv = NULL; | |
} | |
if (decoded) { | |
HeapFree(GetProcessHeap(), 0, decoded); | |
decoded = NULL; | |
} | |
if (ivandcipher) { | |
HeapFree(GetProcessHeap(), 0, ivandcipher); | |
ivandcipher = NULL; | |
} | |
if (key) { | |
CryptDestroyKey(key); | |
key = NULL; | |
} | |
if (hCryptProv) { | |
CryptReleaseContext(hCryptProv, 0); | |
hCryptProv = NULL; | |
} | |
return plaintext; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment