使用OpenSSL API实现Windows CryptoAPI CryptDeriveKey

时间:2011-01-25 12:38:08

标签: c encryption cross-platform openssl cryptoapi

我有一个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 个答案:

答案 0 :(得分:3)

毕竟,这段代码有效:

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;
}

希望这会对某人有所帮助。