2011-01-25 65 views
4

我有一個CryptoAPI代碼來使用AES-128加密\解密給定數據和使用SHA-256從密碼派生的密鑰。使用OpenSSL API實現Windows CryptoAPI CryptDeriveKey

如何編寫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 

回答

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

希望這會幫助別人。

+0

據我所知,結果32字節的SHA256,前16個字節將是密鑰,剩餘的16個字節將是IV。 帶20個字節的SHA1如何? – yelliver 2016-11-30 07:28:06