gpt4 book ai didi

public-key-encryption - 如何使用证书加密数据?

转载 作者:行者123 更新时间:2023-12-02 05:28:36 29 4
gpt4 key购买 nike

如何使用 Microsoft Crypto API 中的“证书” 加密数据?


我知道如何使用 AES 加密通过 Microsoft Crypto API 加密数据:

keyBlob.hdr.bType := PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion := CUR_BLOB_VERSION;
keyBlob.hdr.reserved := 0;
keyBlob.hdr.aiKeyAlg := CALG_AES_128;
keyBlob.cbKeySize := 16;
Move(data[0], keyBlob.key[0], 16);


/*
Set ProviderName to either
providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider"
providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" //Windows XP and earlier
*/
MS_ENH_RSA_AES_PROV_W: WideString = 'Microsoft Enhanced RSA and AES Cryptographic Provider';
providerName := MS_ENH_RSA_AES_PROV_W;

CryptAcquireContextW(provider, nil, PWideChar(providerName), PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
CryptImportKey(provider, PByte(@keyBlob), sizeof(keyBlob), 0, 0, importedKey);

mode := CRYPT_MODE_CBC;
CryptSetKeyParam(importedKey, KP_MODE, @mode, 0);

//CryptEncrypt encrypts in-place. Copy stuff to be encrypted into new byte buffer
utf8PlainText := TCrypt.WideStringToUTF8(szPlainText);
dataLen := Length(utf8PlainText);
bufferLen := dataLen+16; //allocate a buffer larger than we need to hold the data we want to encrypt
SetLength(data, bufferLen);
Move(utf8PlainText[1], data[0], dataLen);

if not CryptEncrypt(importedKey, 0, True, 0, @data[0], {var}dataLen, bufferLen) then
begin
le := GetLastError;
if le = ERROR_MORE_DATA then
begin
/*
If the buffer allocated for pbData is not large enough to hold the encrypted data,
GetLastError returns ERROR_MORE_DATA and stores the required buffer size,
in bytes, in the DWORD value pointed to by pdwDataLen.
*/
bufferLen := dataLen;
SetLength(data, bufferLen);
CryptEncrypt(importedKey, 0, True, 0, @data[0], {var}dataLen, bufferLen);
end;
CryptDestroyKey(importedKey);
CryptReleaseContext(provider, 0);
end;

现在我需要做同样的事情,除了我需要使用公钥加密和私钥解密而不是对称加密。


注意:这15行对称加密的代码花了3天的时间。我希望有人能在我用头撞墙一周后与我保持一致,但我最终走上了错误的道路,认为我必须安装 OpenSSL。更糟糕的是,如果我尝试调用 COM Objects from native code

注意:我只是将代码示例包含在内,作为用无关紧要的垃圾填满问题的一种方式。如果问题只包含一行,有些人会投票关闭该问题。

最佳答案

Microsoft Crypto API 包含使用证书进行非对称加密和解密的高级函数。查看 CryptEncryptessageCryptDecryptMessage

在解密情况下,您的 CERT_CONTEXT 必须具有 CERT_KEY_PROV_INFO_PROP_ID 属性。

我可以给你一个用法的例子:

const wchar_t message[] = L"This is a simple test message.";
PCCERT_CONTEXT hCert = NULL;
HCERTSTORE hStore = NULL;

static bool openCertStoreMY(CDialog *parent)
{
if(!hStore)
{
hStore = CertOpenSystemStore(NULL, L"MY");

if(!hStore)
{
parent->MessageBox(L"Cannot open \"MY\"", L"Error", MB_ICONERROR);
return false;
}
}

return true;
}

void CTestDlg::OnEncryptClicked()
{
if(!hCert)
{
if(!openCertStoreMY(this))
return;

hCert = CryptUIDlgSelectCertificateFromStore(hStore, GetSafeHwnd(), NULL, NULL, 0, 0, 0);

if(!hCert)
return;
}

CRYPT_ENCRYPT_MESSAGE_PARA params;
memset(&params, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
params.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
params.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
params.ContentEncryptionAlgorithm.pszObjId = "2.16.840.1.101.3.4.1.2"; //AES128

DWORD msz;
DWORD cbMsg = sizeof(message);
const BYTE *pbMsg = (PBYTE)message;
if(!CryptEncryptMessage(&params, 1, &hCert, pbMsg, cbMsg, NULL, &msz))
return;

PBYTE outBuf = new BYTE[msz];
if(CryptEncryptMessage(&params, 1, &hCert, pbMsg, cbMsg, outBuf, &msz))
{
FILE *fil = _wfopen(filename, L"wb");
if(fil)
{
fwrite(outBuf, 1, msz, fil);
fclose(fil);
MessageBox(L"Complete");
}
else
MessageBox(L"Cannot open file", L"Error", MB_ICONERROR);
}

delete [] outBuf;
}

void CTestDlg::OnDecryptClicked()
{
if(!openCertStoreMY(this))
return;

CRYPT_DECRYPT_MESSAGE_PARA params;
params.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
params.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
params.cCertStore = 1;
params.rghCertStore = &hStore;
params.dwFlags = 0;

DWORD cbMsg;
PBYTE pbMsg;

FILE *fil = _wfopen(filename, L"rb");
if(fil)
{
fseek(fil, 0 ,2);
cbMsg = ftell(fil);
fseek(fil, 0, 0);
pbMsg = new BYTE[cbMsg];

fread(pbMsg, 1, cbMsg, fil);
fclose(fil);
} else {
MessageBox(L"Cannot open file", L"Error", MB_ICONERROR);
return;
}

DWORD msz;
if(!CryptDecryptMessage(&params, pbMsg, cbMsg, NULL, &msz, NULL))
{
delete [] pbMsg;
return;
}

PBYTE outBuf = new BYTE[msz];
if(CryptDecryptMessage(&params, pbMsg, cbMsg, outBuf, &msz, NULL))
MessageBox((LPCWSTR)outBuf);

delete [] pbMsg;
delete [] outBuf;
}

关于public-key-encryption - 如何使用证书加密数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12714948/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com