Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten artykuł zawiera informacje o tym, kiedy należy używać określonych flag podczas wywoływania elementu CryptAcquireContext i przyczyn używania tych flag.
Oryginalny numer KB: 238187
Podsumowanie
CryptAcquireContext
Wywołania funkcji mogą zawierać różne flagi. Ważne jest, aby wiedzieć, kiedy używać tych flag. Ten artykuł zawiera informacje o tym, kiedy należy używać określonych flag podczas wywoływania CryptAcquireContext
i przyczyn używania tych flag.
Więcej informacji
Operacje klucza prywatnego nie są wykonywane
Jeśli nie używasz utrwalonego klucza prywatnego, flaga CRYPT_VERIFYCONTEXT (0xF0000000) może być używana podczas wywoływania elementu CryptAcquireContext. Informuje to cryptoAPI o utworzeniu kontenera kluczy w pamięci, który zostanie wydany po wywołaniu funkcji CryptReleaseContext. Gdy ta flaga jest używana, parametr pszContainer musi mieć wartość NULL. Flaga CRYPT_VERIFYCONTEXT może być używana w następujących scenariuszach:
Tworzysz skrót.
Generujesz klucz symetryczny do szyfrowania lub odszyfrowywania danych.
Wyprowadzasz klucz symetryczny z skrótu w celu szyfrowania lub odszyfrowywania danych.
Weryfikujesz podpis. Istnieje możliwość zaimportowania klucza publicznego z obiektu PUBLICKEYBLOB lub certyfikatu przy użyciu klucza CryptImportKey lub CryptImportPublicKeyInfo.
Planujesz wyeksportować klucz symetryczny, ale nie importować go w okresie istnienia kontekstu kryptograficznego.
Uwaga 16.
Kontekst można uzyskać przy użyciu flagi CRYPT_VERIFYCONTEXT, jeśli planujesz zaimportować klucz publiczny tylko w dwóch ostatnich scenariuszach.
Wykonujesz operacje klucza prywatnego, ale nie używasz utrwalonego klucza prywatnego przechowywanego w kontenerze kluczy.
Operacje klucza prywatnego są wykonywane
Jeśli planujesz wykonywać operacje klucza prywatnego, należy wziąć pod uwagę wiele problemów.
Najlepszym sposobem uzyskania kontekstu jest próba otwarcia kontenera. Jeśli ta próba zakończy się niepowodzeniem z komunikatem "NTE_BAD_KEYSET", utwórz kontener przy użyciu flagi CRYPT_NEWKEYSET.
Uwaga 16.
Aplikacje nie mogą używać domyślnego kontenera kluczy, przekazując wartość NULL dla nazwy kontenera do przechowywania kluczy prywatnych. Jeśli wiele aplikacji korzysta z tego samego kontenera, jedna aplikacja może zmienić lub zniszczyć klucze, których potrzebuje inna aplikacja. Jeśli aplikacje używają kontenerów kluczy o unikatowej nazwie, ryzyko zostanie zmniejszone w przypadku innych aplikacji manipulowania kluczami, które są niezbędne do prawidłowej funkcji.
// Acquire Context of container that is unique to each user.
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
// Error ...
}
}
}
// Or, acquire Context of container that is shared across the machine.
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)
{
// Error ...
}
}
}
Używanie flagi CRYPT_MACHINE_KEYSET
Jeśli nie wykonujesz operacji klucza prywatnego na podstawie poszczególnych użytkowników i potrzebujesz globalnych operacji klucza prywatnego, należy użyć CRYPT_MACHINE_KEYSET. Ta metoda tworzy parę kluczy prywatnych/publicznych na poszczególnych komputerach. Niektóre konkretne scenariusze, w których należy użyć CRYPT_MACHINE_KEYSET, to:
- Piszesz usługę.
- Składnik działa na stronie Active Server Pages (ASP).
- Składnik jest składnikiem serwera transakcji firmy Microsoft (MTS). W tych przykładach jest używana CRYPT_MACHINE_KEYSET, ponieważ kontekst zabezpieczeń, w którym aplikacja jest uruchomiona, nie ma dostępu do profilu użytkownika. Na przykład klient usługi MTS może personifikować użytkownika, ale profil użytkownika nie jest dostępny, ponieważ użytkownik nie jest zalogowany. To samo dotyczy składnika, który jest uruchomiony na stronie ASP.
Zapewnianie dostępu do kontenera
Domyślnie po utworzeniu kontenera kluczy system lokalny i twórca są jedynymi użytkownikami, którzy mają dostęp do kontenera. Wyjątkiem jest utworzenie kontenera kluczy przez administratora. System lokalny i wszyscy inni administratorzy będą mieli dostęp do kontenera kluczy. Żaden inny kontekst zabezpieczeń nie może otworzyć kontenera.
Jeśli kod będzie uruchamiany w więcej niż jednym kontekście zabezpieczeń, musisz przyznać odpowiednim użytkownikom dostęp do kontenera.
Aby ustawić zabezpieczenia w kontenerze, wywołaj funkcję CryptSetProvParam z flagą PP_KEYSET_SEC_DESCR po utworzeniu kontenera. Ta metoda umożliwia ustawienie deskryptora zabezpieczeń w kontenerze.
Poniższy kod pokazuje, jak wywołać metodę CryptSetProvParam. Odbywa się to natychmiast po utworzeniu kontenera kluczy.
// Acquire Context
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
// Error ...
}
// Create Security Descriptor (pSD)...
// Set the Security Descriptor on the container
if (!CryptSetProvParam(hProv,
PP_KEYSET_SEC_DESCR,
pSD,
DACL_SECURITY_INFORMATION))
{
// Error ...
}
}
}
Błędy CryptAcquireContext
Poniżej przedstawiono najczęstsze kody błędów i możliwe przyczyny błędu.
- NTE_BAD_KEYSET (0x80090016)
- Kontener kluczy nie istnieje.
- Nie masz dostępu do kontenera kluczy.
- Usługa chronionego magazynu nie jest uruchomiona.
- NTE_EXISTS (0x8009000F)
- Kontener kluczy już istnieje, ale próbujesz go utworzyć. Jeśli poprzednia próba otwarcia klucza nie powiodła się z NTE_BAD_KEYSET, oznacza to, że dostęp do kontenera kluczy zostanie odrzucony.
- NTE_KEYSET_NOT_DEF (0x80090019)
- Dostawca usług kryptograficznych (CSP) może nie być poprawnie skonfigurowany. Użycie Regsvr32.exe w bibliotekach DLL CSP (Rsabase.dll lub Rsaenh.dll) może rozwiązać problem, w zależności od używanego dostawcy.