CryptAcquireContext() kullanımı ve sorun giderme

Bu makalede, CryptAcquireContext'i çağırdığınızda belirli bayrakların ne zaman kullanılacağı ve bu bayrakları kullanmanın nedenleri hakkında bilgi sağlanır.

Şunlar için geçerlidir: Windows Server 2012 R2
Özgün KB numarası: 238187

Özet

İşleve yapılan CryptAcquireContext çağrılar çeşitli bayraklar içerebilir. Bu bayrakların ne zaman kullanılacağını bilmek önemlidir. Bu makalede, çağırdığınızda CryptAcquireContext belirli bayrakların ne zaman kullanılacağı ve bu bayrakları kullanmanın nedenleri hakkında bilgi sağlanır.

Daha fazla bilgi

Özel anahtar işlemleri gerçekleştirilmiyor

Kalıcı bir özel anahtar kullanmadığınızda, CryptAcquireContext çağrıldığında CRYPT_VERIFYCONTEXT (0xF0000000) bayrağı kullanılabilir. Bu, CryptoAPI'ye bellekte CryptReleaseContext çağrıldığında yayınlanacak bir anahtar kapsayıcısı oluşturmasını söyler. Bu bayrak kullanıldığında pszContainer parametresi NULL olmalıdır. CRYPT_VERIFYCONTEXT bayrağı aşağıdaki senaryolarda kullanılabilir:

  • Karma oluşturuyorsunuz.

  • Verileri şifrelemek veya şifresini çözmek için simetrik bir anahtar oluşturuyorsunuz.

  • Verileri şifrelemek veya şifresini çözmek için bir karmadan simetrik anahtar türetiyorsunuz.

  • İmzayı doğrulusunuz. CryptImportKey veya CryptImportPublicKeyInfo kullanarak ortak anahtarı PUBLICKEYBLOB'dan veya bir sertifikadan içeri aktarmak mümkündür.

  • Simetrik anahtarı dışarı aktarmayı planlıyorsunuz ancak şifreleme bağlamı ömrü içinde içeri aktarmayı planlamıyorsunuz.

    Not

    Yalnızca son iki senaryo için ortak anahtarı içeri aktarmayı planlıyorsanız, bağlam CRYPT_VERIFYCONTEXT bayrağı kullanılarak elde edilebilir.

  • Özel anahtar işlemleri gerçekleştiriyor, ancak bir anahtar kapsayıcısında depolanan kalıcı bir özel anahtar kullanmıyorsunuz.

Özel anahtar işlemleri gerçekleştirilir

Özel anahtar işlemleri gerçekleştirmeyi planlıyorsanız dikkate almanız gereken birçok sorun vardır.

Bağlam edinmenin en iyi yolu kapsayıcıyı açmayı denemektir. Bu girişim "NTE_BAD_KEYSET" ile başarısız olursa, CRYPT_NEWKEYSET bayrağını kullanarak kapsayıcıyı oluşturun.

Not

Uygulamalar, özel anahtarları depolamak için kapsayıcı adı için NULL geçirerek varsayılan anahtar kapsayıcısını kullanmamalıdır. Birden çok uygulama aynı kapsayıcıyı kullandığında, bir uygulama başka bir uygulamanın kullanılabilir olması gereken anahtarları değiştirebilir veya yok edebilir. Uygulamalar benzersiz bir ada sahip anahtar kapsayıcıları kullanıyorsa, düzgün işlev için gerekli olan anahtarlarla oynanan diğer uygulamaların riski azalır.

// 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 ...
 }
 }
}

CRYPT_MACHINE_KEYSET bayrağını kullanma

Kullanıcı başına özel anahtar işlemleri gerçekleştirmiyorsanız ve genel özel anahtar işlemlerine ihtiyacınız varsa CRYPT_MACHINE_KEYSET kullanılmalıdır. Bu yöntem, bilgisayar başına özel/ortak anahtar çiftini oluşturur. CRYPT_MACHINE_KEYSET kullanılması gereken bazı belirli senaryolar şunlardır:

  • Bir hizmet yazıyorsun.
  • Bileşeniniz bir Active Server Pages (ASP) sayfası altında çalışıyor.
  • Bileşeniniz bir Microsoft Transaction Server (MTS) bileşenidir. Bu örnekler için, uygulamanın çalıştığı güvenlik bağlamı bir kullanıcı profiline erişimi olmadığından CRYPT_MACHINE_KEYSET kullanılır. Örneğin, bir MTS istemcisi bir kullanıcının kimliğine bürünebilir, ancak kullanıcı oturum açmadığından kullanıcının profili kullanılamaz. Aynı durum, ASP sayfası altında çalışan bir bileşen için de geçerlidir.

Kapsayıcınıza erişim sağlama

Varsayılan olarak, bir anahtar kapsayıcısı oluşturulduğunda, kapsayıcıya erişimi olan tek kullanıcılar yerel sistem ve oluşturucudur. Bunun istisnası, yöneticinin anahtar kapsayıcısını oluşturmasıdır. Yerel sistem ve diğer tüm yöneticiler anahtar kapsayıcısına erişebilir. Diğer güvenlik bağlamları kapsayıcıyı açamaz.

Kodunuz birden fazla güvenlik bağlamı altında çalışacaksa, uygun kullanıcılara kapsayıcınıza erişim vermeniz gerekir.

Kapsayıcıdaki güvenliği ayarlamak için, kapsayıcı oluşturulduktan sonra PP_KEYSET_SEC_DESCR bayrağıyla CryptSetProvParam işlevini çağırın. Bu yöntem, kapsayıcıda güvenlik tanımlayıcısını ayarlamanıza olanak tanır.

Aşağıdaki kodda CryptSetProvParam'ın nasıl çağrılması gösterilmektedir. Bu işlem anahtar kapsayıcısı oluşturulduktan hemen sonra gerçekleştirilir.

// 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 ...
 }
 }
}

CryptAcquireContext hataları

En yaygın hata kodları ve hatanın olası nedenleri aşağıdadır.

  • NTE_BAD_KEYSET (0x80090016)
    • Anahtar kapsayıcısı yok.
    • Anahtar kapsayıcısına erişiminiz yok.
    • Korumalı Depolama Hizmeti çalışmıyor.
  • NTE_EXISTS (0x8009000F)
    • Anahtar kapsayıcısı zaten var, ancak oluşturmaya çalışıyorsunuz. Anahtarı önceki bir açma girişimi NTE_BAD_KEYSET ile başarısız olduysa, anahtar kapsayıcısına erişimin reddedildiğini gösterir.
  • NTE_KEYSET_NOT_DEF (0x80090019)
    • Şifreleme Hizmeti Sağlayıcısı (CSP) doğru ayarlanmamış olabilir. KULLANıLAN sağlayıcıya bağlı olarak CSP DLL'lerinde (Rsabase.dll veya Rsaenh.dll) Regsvr32.exe kullanılması sorunu çözebilir.