Идея состоит в том, чтобы два приложения имели общий секретный ключ CNG.
Приложения A и B создают (или импортируют) сертификат.При создании он использует CertCreateSelfSignCertificate()
с дескриптором NCryptCreatePersistedKey()
.
Приложения сериализуют свой сертификат (CertSerializeCertificateStoreElement()
) и передают на другой конец.
Приложение 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);
}