2012-03-20 4 views
3

Я написал код с использованием Microsoft CryptoAPI для вычисления SHA-1 и получил скомпилированный exe, работающий на Windows 7, Win Server 2008, Win Server 2003. Однако, когда я запускаю его под Windows XP SP3, он не работает.MS CryptoAPI не работает в Windows XP с CryptAcquireContext()

Я сузил отказ от вызова CryptAcquireContext().

я заметил, что a previous post говорил о XP неисправного именование «... (прототип)», и это должно быть учтено с помощью определенного MS_ENH_RSA_AES_PROV_XP макро WinXP.

Я сделал модификацию кода XP, и он все еще не работает. (В bResult возвращает 0 ложных на Win XP, все остальные платформы bResult возвращает 1 истинные.)

Я проверил MS_ENH_RSA_AES_PROV_XP с фактическим ключом + строковые значениями, которые я вижу в regedit.exe, так что все выглядит как он настроен на работу, но нет успеха.

Я пропустил что-то, чтобы заставить его работать в Windows XP?

Я наклеил кратчайший возможный пример, чтобы проиллюстрировать проблему. Я использовал VS2010 C++.

// based on examples from http://msdn.microsoft.com/en-us/library/ms867086.aspx 

#include "windows.h" 
#include "wincrypt.h" 
#include <iostream> 
#include <iomanip> // for setw() 

void main() 
{ 
    BOOL bResult; 
    HCRYPTPROV hProv; 

    // Attempt to acquire a handle to the default key container. 
    bResult = CryptAcquireContext(
     &hProv,   // Variable to hold returned handle. 
     NULL,    // Use default key container. 
     MS_DEF_PROV,  // Use default CSP. 
     PROV_RSA_FULL,  // Type of provider to acquire. 
     0);    // No special action. 
    std::cout << "line: " << std::setw(4) << __LINE__ << "; " << "bResult = " << bResult << std::endl; 

    if (! bResult) {  // try Windows XP provider name 
     bResult = CryptAcquireContext(
      &hProv,   // Variable to hold returned handle. 
      NULL,    // Use default key container. 
      MS_ENH_RSA_AES_PROV_XP, // Windows XP specific instead of using default CSP. 
      PROV_RSA_AES,  // Type of provider to acquire. 
      0);    // No special action. 
     std::cout << "line: " << std::setw(4) << __LINE__ << "; " << "bResult = " << bResult << std::endl; 
    } 

    if (bResult) 
     CryptReleaseContext(hProv, 0); 
} 

Windows 7 успех: enter image description here

провал Windows XP: enter image description here

ответ

5

В коде CryptAcquireContext, по-видимому, вам не хватает параметр, чтобы получить контекст без определенного набора контейнеров. Вам необходимо передать параметр CRYPT_VERIFYCONTEXT в CryptAcquireContext.

Windows 7 может работать вокруг этого.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx

Для дальнейшей диагностики, результаты GetLastError() будет необходимым условием.

+0

Да, это сработало! Спасибо. В онлайн-примерах Microsoft, в которых я скопировал код, у меня не было этого параметра. Но чтобы добавить к путанице, когда я добавляю CRYPT_VERIFYCONTEXT к первому вызову, который не использует MS_ENH_RSA_AES_PROV_XP, он также работает на XP! Странно, но я возьму его. – JasDev