1

名前キー コンテナーでキーを生成した Windows 7 を実行している一部のシステムで、ユーザーのパスワードを変更すると、CryptAcquireCertificatePrivateKey() を呼び出すと、エラー CRYPT_E_NO_KEY_PROPERTY (0x8009200B) が発生します。

これは、すべてのボックスで発生するわけではありません。当初、これはネットワーク上にないドメイン マシンが原因であると考えられていたため、ドメインの内容を更新できませんでしたが、一部のスタンドアロン マシンで再現することができました。

キーを読み取るための私のコード

if((StoreHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, QWARQ_CERT_STORE_NAME)) != NULL)
     {
        /* Look for certificate with matching user guid.            */
        if((CertContext = CertFindCertificateInStore(StoreHandle,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR,DataBuffer, NULL)) != NULL)
        {
           if(CryptAcquireCertificatePrivateKey(CertContext, 0,NULL, &CryptProvHandle, &KeySpec, &FreeHandle))
           {
           }
           else
           {
                   DWORD dwError=GetLastError();   //CRYPT_E_NO_KEY_PROPERTY
           }
        }
     }

キー/キーコンテナを生成するコードは次のとおりです

if(CryptAcquireContext(&hCryptProv,KEY_CONTAINER_NAME, NULL,PROV_RSA_FULL, 0) == FALSE) //CRYPT_NEWKEYSET
{
    DWORD result = GetLastError();
    if (NTE_BAD_KEY_STATE  == result)
    {
        DebugLogging::DbgPrintF(TEXT("[CertInitialization] NTE_BAD_KEY_STATE - user has changed his password \n"), result);
        return false;
    }
    else if (NTE_BAD_KEYSET != result)
    {
        DebugLogging::DbgPrintF(TEXT("[CertInitialization] could not acquire CSP[0x%x]\n"), result);
        return false;
    }

    if(CryptAcquireContext(&hCryptProv, KEY_CONTAINER_NAME, NULL,PROV_RSA_FULL, CRYPT_NEWKEYSET) == FALSE) //CRYPT_NEWKEYSET
    {
        DWORD result = GetLastError();
        DebugLogging::DbgPrintF(TEXT("[CertInitialization] could not acquire CSP from new keyset[0x%x]\n"), result);
        return false;
    }
}
if(CryptGenKey(hCryptProv, AT_KEYEXCHANGE, RSA2048BIT_KEY |CRYPT_EXPORTABLE, &hKey)== FALSE)
{
    DebugLogging::DbgPrintF(TEXT("CertGeneration() could not generate key[%d]\n"),GetLastError());
    return false;
} 
4

1 に答える 1

1

DPAPI についてさらに学習した後

パスワードの変更

この方法では、パスワードの変更中にユーザーのマスター キーへのアクセスが継続されます。DPAPI は、Active Directory ドメインでのパスワード変更操作中に Winlogon コンポーネントによって呼び出されます。

* DPAPI receives notification from Winlogon during a password change operation.
* DPAPI decrypts all master keys that were encrypted with the user's old passwords.
* DPAPI re-encrypts all master keys with the user's new password.

パスワードのリセット (設定)

この方法では、管理者はユーザーのパスワードを強制的にリセットします。パスワードのリセットは、パスワードの変更よりも複雑です。管理者はユーザーとしてログオンしておらず、ユーザーの古いパスワードにアクセスできないため、その古いパスワードを使用して古いマスター キーを復号化し、新しいパスワードで再暗号化することはできません。

于 2010-02-16T23:48:46.043 に答える