我正在尝试使用wincryptencryption文本消息。 我的代码是不可预知的。 它不encryption/解密整个明文,但只是其中的一部分。 如果我更改密码的长度(例如“password123”),它将encryption/解密不同数量的字符。 这是我的代码。
#include <windows.h> #include <wincrypt.h> #include <stdio.h> int main() { const char* passw = "password12"; const char* toencrypt = "consectetur adipiscing elit. In tellus nisl, sodales non arcu quis, sagittis maximus orci cras amet."; HCRYPTPROV hProv; HCRYPTHASH hHash; HCRYPTKEY hKey; DWORD todwSize = (DWORD)strlen(toencrypt); PBYTE pBuffer; CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash); CryptHashData(hHash, (BYTE*)passw, strlen(passw), 0); CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey); //-------------------------------------------------------------------- CryptEncrypt(hKey, 0, TRUE, 0, NULL, &todwSize, todwSize); pBuffer = (BYTE *)malloc(todwSize); strcpy((char*)pBuffer, toencrypt); CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, todwSize); PBYTE pBreturn = pBuffer; const char* message = (const char*)pBreturn; printf("%s", message); //-------------------------------------------------------------------- DWORD dwSize = (DWORD)strlen(message); PBYTE depBuffer; depBuffer = (BYTE *)malloc(1460); strcpy((char*)depBuffer, message); CryptDecrypt(hKey, 0, TRUE, 0, depBuffer, &dwSize); CryptDestroyKey(hKey); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); if(GetLastError() != 0) { printf("%d", GetLastError()); } PBYTE depBreturn = depBuffer; printf("%s", (const char*)depBreturn); printf("\n%d", strlen(message)); return 0; }
预先感谢您的帮助!
认为你的代码加密没问题,但是由于你在调用CryptDecrypt
使用了错误的长度,所以不能解密整个消息
你的主要错误是DWORD dwSize = (DWORD)strlen(message);
和strcpy((char*)depBuffer, message);
但消息是加密的缓冲区,不是0终止ansi字符串。 所以你不能在加密数据上使用strlen
或strcpy
– 你有CryptEncrypt
返回的加密数据长度: todwSize
– 所以你必须和memcpy
使用,如果你需要拷贝加密的缓冲区并把todwSize
传递给CryptDecrypt
还怎么注意Harry Johnston
你在调用CryptEncrypt
不正确的使用明文数据/缓冲区大小。
必须在第一次调用时CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0)
(最后一个参数为CryptEncrypt
dwBufLen必须为0,因为您使用NULL作为缓冲区,并且需要使用另一个变量DWORD needSize
获取加密缓冲区的大小,并不覆盖纯文本缓冲区大小( todwSize
),然后分配给needSize
缓冲区,复制到它的todSize
和调用CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize)
。但是,对于RC4加密和纯文本大小总是相等的,所以需要needSize == todSize
总是在RC4的情况下
你也需要调用CryptAcquireContext
一次,标志CRYPT_VERIFYCONTEXT
在你的情况。 总是需要检查功能结果。 所以测试代码可以是这样的
int main() { const char* passw = "password12"; const char* toencrypt = "consectetur adipiscing elit. In tellus nisl, sodales non arcu quis, sagittis maximus orci cras amet."; HCRYPTPROV hProv; HCRYPTHASH hHash; HCRYPTKEY hKey; DWORD todwSize = (DWORD)strlen(toencrypt), needSize; PBYTE pBuffer; if (CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { if (CryptHashData(hHash, (BYTE*)passw, (DWORD)strlen(passw), 0) && CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey)) { if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0)) { memcpy(pBuffer = (BYTE *)_alloca(needSize), toencrypt, todwSize); if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize)) { if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize)) { if (memcmp(pBuffer, toencrypt, strlen(toencrypt))) { __debugbreak(); } } } } CryptDestroyKey(hKey); } CryptDestroyHash(hHash); } CryptReleaseContext(hProv, 0); } return 0; }