代码之家  ›  专栏  ›  技术社区  ›  SonicBison

在Win 7下更改带命名密钥容器的密码信息

  •  1
  • SonicBison  · 技术社区  · 16 年前

    在运行Windows7的某些系统上,我们在 当我们调用 CryptAcquireCertificatePrivateKey()我们得到一个错误 crypt_e_no_key_属性(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;
    } 
    
    1 回复  |  直到 16 年前
        1
  •  1
  •   SonicBison    16 年前

    了解更多有关DPAPI的信息后

    密码更改

    在这种方法中,在密码更改期间,用户的主密钥的访问是连续的。在Active Directory域中的密码更改操作期间,Winlogon组件调用DPAPI:

    * 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.
    

    密码重置(设置)

    在此方法中,管理员强制重置用户密码。密码重置比密码更改更复杂。由于管理员没有以用户身份登录,也没有访问用户旧密码的权限,因此旧密码不能用于解密旧的主密钥并用新密码重新加密。

    推荐文章