CryptDeriveKey seems to create different keys with the same initial values?

From: Rauno Uusitalo (rauno.uusitalo_at_no_spam.fi)
Date: 09/18/03


Date: Thu, 18 Sep 2003 12:07:11 +0300

Hi there!

Hope somebody could point out what am I doing wrong. Purpose is to create functions to encrypt and decrypt strings by a given password. To me it seems like the CryptDeriveKey-calls are generating different keys with the same passwords resulting unability to decrypt the string. Please help!

Best Regards,
Rauno Uusitalo
  #include <wincrypt.h>
  #include <malloc.h>
  #include <stdio.h>

  void EncryptStr(LPCTSTR szString,
                         LPCTSTR szPassword,
                         LPVOID* ppBuf,
                         DWORD* pBufSize)
  {
      HCRYPTPROV hProv = NULL;
      HCRYPTHASH hHash = NULL;
      HCRYPTKEY hKey = NULL;
      LPTSTR szEncrypted = NULL;

      *ppBuf = NULL;
      *pBufSize = 0;

      if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT))
          CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT);

      if (NULL != hProv)
      {
          if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
          {
              if (CryptHashData(hHash, reinterpret_cast<BYTE*>(const_cast<LPTSTR>(szPassword)), lstrlen(szPassword) * sizeof *szPassword, 0))
                  if (CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
                  {
                      DWORD size = (lstrlen(szString) + 1) * sizeof *szString;

                      *pBufSize = size;

                      if (CryptEncrypt(hKey, NULL, TRUE, 0, NULL, pBufSize, 0))
                          CryptEncrypt(hKey, NULL, TRUE, 0, reinterpret_cast<BYTE*>(malloc(*pBufSize)), pBufSize, *pBufSize);

                      CryptDestroyKey(hKey);
                  }

              CryptDestroyHash(hHash);
          }

      CryptReleaseContext(hProv, 0);
      }
  }

  LPTSTR DecryptStr(LPVOID pBuf,
                                DWORD bufSize,
                                LPCTSTR szPassword)
  {
      HCRYPTPROV hProv = NULL;
      HCRYPTHASH hHash = NULL;
      HCRYPTKEY hKey = NULL;
      BYTE* pDecrypted = NULL;

      if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT))
          CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT);

      if (NULL != hProv)
      {
          if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
          {
              if (CryptHashData(hHash, reinterpret_cast<BYTE*>(const_cast<LPTSTR>(szPassword)), lstrlen(szPassword) * sizeof *szPassword, 0))
                  if (CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
                  {
                      pDecrypted = reinterpret_cast<BYTE*>(malloc(bufSize));
                      CryptDecrypt(hKey, NULL, TRUE, 0, pDecrypted, &bufSize);
                      CryptDestroyKey(hKey);
                  }

              CryptDestroyHash(hHash);
          }

      CryptReleaseContext(hProv, 0);
      }

  return reinterpret_cast<LPTSTR>(pDecrypted);
  }

  int _tmain(int argc, _TCHAR* argv[])
  {
      LPCTSTR szPlainText = _T("ABC");
      LPCTSTR szPassword = _T("Password");
      LPVOID pBuf = NULL;
      DWORD bufSize = 0;

      EncryptStr(szPlainText, szPassword, &pBuf, &bufSize);

      LPTSTR szDecrypt = DecryptStr(pBuf, bufSize, szPassword);
      
      _tprintf(_T("%s\n"), szDecrypt);
      
      free(szDecrypt);
      free(pBuf);
  }



Relevant Pages