Реализация Windows CryptoAPI CryptDeriveKey с использованием API-интерфейсов OpenSSL - PullRequest
4 голосов
/ 25 января 2011

У меня есть код CryptoAPI для шифрования \ дешифрования данных с использованием AES-128 и ключ, полученный из пароля с использованием SHA-256.

Как я могу написать эквивалентную реализацию OpenSSL, чтобы иметь возможность зашифровать данные с ее помощью, затем расшифровать ее с помощью CryptoAPI и наоборот?

Попытка использовать EVP_BytesToKey с EVP_aes_128_cbc () и EVP_sha256 () не работала «как есть». (Под «не работает» я имею в виду - не может расшифровать зашифрованные данные, созданные CryptoAPI, и наоборот. Это работает для расшифровки зашифрованных данных OpenSSL).

Любая идея или хорошая ссылка?

Заранее спасибо.

Вот код Windows CryptoAPI:

// Get the handle to the default provider. 
      if(CryptAcquireContext(
                   &hCryptProv, 
                   NULL, 
                   MS_ENH_RSA_AES_PROV, 
                   PROV_RSA_AES, 
                   CRYPT_VERIFYCONTEXT))
          {
                   _tprintf(
                             TEXT("A cryptographic provider has been acquired. \n"));
          }
          else
          {
                   goto Exit_PrepareCAPI;
          }
          // Create a hash object. 
          if(!CryptCreateHash(
                   hCryptProv, 
                   HASH_ALGORITHM, 
                   0, 
                   0, 
                   &hHash))
          {
                   goto Exit_PrepareCAPI;
          }
          // Hash in the password data. 
          if(!CryptHashData(
                   hHash, 
                   (BYTE*) strPassword.c_str(),
                   strPassword.length(),
                   (DWORD)0)) 
          {
                   goto Exit_PrepareCAPI;
          }
          // Derive a session key from the hash object. 
          if(!CryptDeriveKey(
                   hCryptProv, 
                   ENCRYPT_ALGORITHM, 
                   hHash, 
                    0x00800000 /*128 bit*/, 
                   &hKey))
          { 
                   goto Exit_PrepareCAPI;
          }
          DWORD cryptMode = CRYPT_MODE_CBC;

          if(!CryptSetKeyParam(
                   hKey, 
                   KP_MODE, 
                   (BYTE*)&cryptMode, 
                   0))
          { 
                   goto Exit_PrepareCAPI;
          }

                   if(!CryptGetHashParam(
                   hHash,
                   HP_HASHSIZE,
                   (BYTE *)&dwHashLen,
                   &dwHashLenSize,
                   0))
          {
                   goto Exit_PrepareCAPI;
          }

          pbHash = new BYTE[dwHashLen];

          if(!CryptGetHashParam(
                   hHash,
                   HP_HASHVAL,
                   pbHash,
                   &dwHashLen,
                   0))
          {
                   goto Exit_PrepareCAPI;
          }

          SecureZeroMemory( ivBuff, sizeof(ivBuff) );

          for(DWORD i = 16, j = 0 ; i < dwHashLen ; i++, j++)
          {
                   ivBuff[j] = pbHash[i];
          }

          if(!CryptSetKeyParam(
                   hKey, 
                   KP_IV, 
                   ivBuff, 
                   0))
          { 
                   goto Exit_PrepareCAPI;
          }
          //
          // Read the data into pre-allocated pbBuffer
          //
// Encrypt data.           if(!CryptEncrypt(
                    hKey, 
                    NULL, 
                    fEOF,
                    0, 
                    pbBuffer, 
                    &dwCount, 
                    dwBufferLen))
{ 
                    goto Exit_MyEncryptFile;
          } 
Exit_MyEncryptFile:
          // Cleanup allocated objects

1 Ответ

3 голосов
/ 15 марта 2011

В конце концов, этот код работал:

int generateKey(const string& strSecter)
{    
SHA256_CTX sha256Ctx;
unsigned char hash[SHA256_DIGEST_LENGTH];
SecureZeroMemory(hash, sizeof hash);
SHA256_Init(&sha256Ctx);
SHA256_Update(&sha256Ctx, strSecter.c_str(), strSecter.length());
SHA256_Final(hash, &sha256Ctx);
memcpy(Key, hash, AES_BLOCK_SIZE);
memcpy(IV, hash + AES_BLOCK_SIZE, AES_BLOCK_SIZE);

return 0;
}

Надеюсь, это кому-нибудь поможет.

...