СПГ Создать общий секрет - PullRequest
0 голосов
/ 09 марта 2019

Идея состоит в том, чтобы два приложения имели общий секретный ключ CNG.

  1. Приложения A и B создают (или импортируют) сертификат.При создании он использует CertCreateSelfSignCertificate() с дескриптором NCryptCreatePersistedKey().

  2. Приложения сериализуют свой сертификат (CertSerializeCertificateStoreElement()) и передают на другой конец.

  3. Приложение A воссоздает сертификат B (CertAddSerializedElementToStore()) и наоборот.

Теперь я должен использовать NCryptSecretAgreement() или BCryptSecretAgreement() для созданияобщий секрет.Проблема заключается в том, что CryptImportPublicKeyInfoEx2() импортирует открытый ключ (из полученного сертификата) в BCRYPT_KEY_HANDLE, где мне потребуется NCRYPT_KEY_HANDLE для вызова NCryptSecretAgreement ().Если я хочу использовать BCryptSecretAgreement (), тогда мне понадобится BCRYPT_KEY_HANDLE, а не то, что CryptAcquireCertificatePrivateKey() вернет.

Как действовать дальше?

shared_ptr<NcryptObject> CreateShared(CertX& priv,CertX& pub)
{
    shared_ptr<NcryptObject> o;

    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE h1 = 0;
    DWORD kt = 0;
    BOOL kb = 0;
    CryptAcquireCertificatePrivateKey(priv.h(), CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, 0, &h1, &kt, &kb);
    if (!h1)
        return nullptr;
    shared_ptr<NcryptObject> k1;
    if (kb)
        k1 = make_shared<NcryptObject>(h1);

    BCRYPT_KEY_HANDLE bc = 0;
    CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING,&pub.h()->pCertInfo->SubjectPublicKeyInfo, 0, 0, &bc);
    if (!bc)
        return 0;

    // whops.
    NCRYPT_SECRET_HANDLE se = 0;
    auto e1 = NCryptSecretAgreement(h1,(NCRYPT_KEY_HANDLE)bc, &se, 0);
    BCRYPT_SECRET_HANDLE se2 = 0;
    auto e2 = BCryptSecretAgreement((BCRYPT_KEY_HANDLE)h1, bc, &se2, 0);


}
...