wincrypt des 加密 8字节补齐 跨平台

发布时间 2023-07-31 11:38:38作者: 一曲沙丶天涯

原理:wincrypt des加密时,如果需要加密的buffer大小不是8字节倍数,它会在数据的末尾添加字节,这些字节的值等于缺少的字节数。

源码:

  #include <openssl/des.h>
  const BYTE IV[] = "12345678";
1
DWORD DESEncrypt(WCHAR* data, char* password, BYTE* buffer, DWORD bufferLength) 2 { 3 DWORD dataLength = STD::my_wcslen(data) * 2; 4 5 if (buffer == NULL || bufferLength < dataLength + 8 - (dataLength % 8) || strlen(password) < 8) return 0; 6 #ifdef WIN32 7 memcpy(buffer, (char*)data, dataLength); 8 HCRYPTPROV hProv = NULL; 9 HCRYPTKEY hSessionKey = NULL; 10 bool bResult = TRUE; 11 KeyBlob blob; 12 blob.header.bType = PLAINTEXTKEYBLOB; 13 blob.header.bVersion = CUR_BLOB_VERSION; 14 blob.header.reserved = 0; 15 blob.header.aiKeyAlg = CALG_DES; 16 blob.cbKeySize = 8; 17 memcpy(blob.rgbKeyData, password, 8); 18 bResult &= CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0); 19 bResult &= CryptImportKey(hProv, (BYTE*)&blob, sizeof(blob), 0, 0, &hSessionKey); 20 bResult &= CryptSetKeyParam(hSessionKey, KP_IV, (BYTE*)IV, 0); 21 bResult &= CryptEncrypt(hSessionKey, NULL, TRUE, 0, (BYTE*)buffer, &dataLength, bufferLength); 22 bResult &= CryptDestroyKey(hSessionKey); 23 bResult &= CryptReleaseContext(hProv, 0); 24 return bResult ? dataLength : 0; 25 #else 26 DES_cblock key; 27 DES_key_schedule schedule; 28 DES_cblock iv; 29 30 // 设置密钥 31 memcpy(key, password, 8); 32 DES_set_key_unchecked(&key, &schedule); 33 34 // 设置初始化向量(IV) 35 memcpy(iv, IV, 8); 36 37 //填充数据长度 38 size_t nPadded = (8 - (dataLength % 8))%8; 39 DWORD paddedDataLength = dataLength + nPadded; 40 void* p = reinterpret_cast<void*>(data)+ dataLength; 41 memset(p, nPadded, nPadded); 42 43 // 加密数据 44 DES_ncbc_encrypt((BYTE*)data, buffer, paddedDataLength, &schedule, &iv, DES_ENCRYPT); 45 46 return paddedDataLength; 47 #endif 48 }