Pergunta

I am using Microsoft CryptoAPI to encrypt the password. Using 3DES from Microsoft Enhanced Cryptographic Provider. What I noticed is that I seem to be getting exactly the same ciphertext from the same plaintext every time. As far as I know this should not be happening in CBC mode, which CALG_3DES is operating in according to MSDN. I know 3DES is old and I should be using AES instead but this is a legacy code and I would like to avoid changing the algorithm. Am I doing something wrong? I think I might need to provide IV but I do not see how it can be done for 3DES using CryptoAPI. None of MSDN samples show it. Below is the redacted code snippet that shows the sequence of CryptoAPI calls.

Here is my code so far:

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);
Foi útil?

Solução

This question was never answered adequately. You can set the IV the same way for any cryptographic algorithm that supports IVs. The Microsoft CryptoAPI deals with variables called HCRYPTKEY for interacting with keys. HCRYPTKEY is nothing special, just a variable that contains a numeric value that is a handle to a key. The Cryptographic Service Provider (CSP) can look up and interact with keys when you use this HCRYPTKEY handle. In your case, call CryptSetKeyParam(hDecEncKey, KP_IV, the_IV_Bytes, 0);. For documentation, see here.

Outras dicas

instead of the following line :

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

use the following lines of code : (change your args accordingly)

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

}

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top