2013-04-04 4 views
2

Я использую Microsoft CryptoAPI для шифрования пароля. Использование 3DES от Microsoft Enhanced Cryptographic Provider. Я заметил, что я, кажется, получаю точно такой же шифрованный текст из одного и того же открытого текста каждый раз. Насколько я знаю, это не должно происходить в режиме CBC, который CALG_3DES работает в соответствии с MSDN. Я знаю, что 3DES старен, и я должен использовать AES вместо этого, но это устаревший код, и я бы хотел избежать изменения алгоритма. Я делаю что-то неправильно? Я думаю, мне, возможно, потребуется предоставить IV, но я не вижу, как это можно сделать для 3DES с использованием CryptoAPI. Ни один из образцов MSDN не показывает это. Ниже приведен отредактированный фрагмент кода, который показывает последовательность вызовов CryptoAPI.Получение такого же зашифрованного текста каждый раз из того же открытого текста

Вот мой код до сих пор:

CryptAcquireContext(&hProvider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); 

/// key acquired by some means and stored in pszTempData 

CryptCreateHash(hProvider, CALG_SHA_256, 0, 0, &hHash); 

CryptHashData(hHash, (BYTE *)pszTempData, wcslen(pszTempData), 0); 

CryptDeriveKey(hProvider, CALG_3DES, hHash, CRYPT_EXPORTABLE, &hDecEncKey); 


// some buffer manipulation to ensure buffer size is of correct size 

CryptEncrypt(hDecEncKey, 0, TRUE, 0, pbBuffer, &dwCount, dwBufferLen); 

CryptBinaryToString(pbBuffer, dwCount, CRYPT_STRING_BINARY, wsTempOut, &dwStrLen); 

ответ

1

Этот вопрос никогда не отвечал адекватно. Вы можете установить IV таким же образом для любого криптографического алгоритма, который поддерживает IV. Microsoft CryptoAPI имеет дело с переменными, называемыми HCRYPTKEY для взаимодействия с ключами. HCRYPTKEY ничего особенного, просто переменная, которая содержит числовое значение, которое является дескриптором ключа. Поставщик криптографических услуг (CSP) может искать и взаимодействовать с ключами при использовании этого дескриптора HCRYPTKEY. В вашем случае звоните CryptSetKeyParam(hDecEncKey, KP_IV, the_IV_Bytes, 0);. Для документации см. here.

0

вместо следующей строки:

CryptAcquireContext(&hProvider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES,  CRYPT_VERIFYCONTEXT); 

использовать следующие строки кода: (изменить арг соответственно)

if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)==0){ 
    //Prateek 12-10-13 
    printf("\n crytpAcquireContext failed..%x.\n",GetLastError()); 
    if(GetLastError()==NTE_BAD_KEYSET){ 
      if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)==0){ 

        printf("\n crytpAcquireContext again failed..%x.\n",GetLastError()); 
      } 
    } 

}