我正在尝试将公钥添加到 Bcrypt 的 diffie Hellman 实现中。 建议创建和导出公钥的示例。就我而言,我已经从客户端获得了公钥。我正在尝试使用该公钥来生成共享会话密钥。当我尝试使用 BCryptImportKeyPair 时,我得到了 STATUS_INVALID_PARAMETER。我创建了 PBCRYPT_DH_KEY_BLOB 并手动添加了这些值。有没有其他方法可以做到这一点?将公共密钥从字符串导入 BCrypt 的示例将不胜感激。
提前致谢。请检查下面的代码。
KeyLength = 1024;//bits
const int sz = 1024;
char * shared_public_key = "48DE15D8E46B857B387E315D518B7D9EDDA1FCA6661CFC9C066B3A352E8644A30BFBB7F84C93818F67B7037235D11A5B0F31E15BCB344C2A7C13E339ED98939CF3F092E64C0DEA28A150404432E3B7077DE3E4D40E421EA88FFAF4D7AD53851912389674B24C80E5FD05D1C60344535159E7A4CAF9F9DCAF712C2A41EF524632";
char * prime = "CBBD1F895B751A803674B4CF6178DAFF87E3AADD017B96CA0D536215091AC55C0D777ADB6206581E7681C5059BEFF7990E4B3DD074266B608800CF7110BE99B861D189A82A26D569CAA2F314E8E79838AEE8DA96380BDFA55B34CA43866B24C0A822947E669C9AA037A8FA765F637663AB4103A9251C70000A689796CE42A2A3";
BYTE OakleyGroup1P[sz /8];
int fld_sz = sz / 8;
string s_prime(prime, fld_sz*2);
transform(s_prime.begin(), s_prime.end(), s_prime.begin(), ::tolower);
string res = "";
for (int i = 0; i < s_prime.size(); i += 2) {
res += s_prime.substr(i, 2);
res += " ";
}
std::istringstream hex_chars_stream(res);
unsigned int c;
int i = 0;
while (hex_chars_stream >> std::hex >> c)
{
OakleyGroup1P[i++] = c;
}
cout << "size of OakleyGroup1P :" << i << endl;
/*for (unsigned char x : OakleyGroup1P) {
cout << ((x >> 4) & 0x0F) << " " << (x & 0x0F) << endl;
}*/
PBYTE PubBlobA2 = new BYTE[sz/8];
string s_shared(shared_public_key, fld_sz * 2);
transform(s_shared.begin(), s_shared.end(), s_shared.begin(), ::tolower);
string temp = "";
for (int i = 0; i < s_shared.size(); i += 2) {
temp += s_shared.substr(i, 2);
temp += " ";
}
std::istringstream hex_chars_stream2(temp);
i = 0;
while (hex_chars_stream2 >> std::hex >> c)
{
PubBlobA2[i++] = c;
}
cout << "size of PubBlobA2 :" << i << endl;
for (int j = 0; j < i; j++) {
cout << ((*(PubBlobA2 + j) >> 4) & 0x0F) << " " << (*(PubBlobA2 + j) & 0x0F) << endl;
}
//
// Construct the DH parameter blob. this is the only supported
// method for DH in CNG.
//
// Calculate size of param blob and allocate memory
DhParamBlobLength = sizeof(BCRYPT_DH_PARAMETER_HEADER) +
sizeof(OakleyGroup1G) +
sizeof(OakleyGroup1P);
DhParamBlob = (PBYTE)HeapAlloc (
GetProcessHeap (),
0,
DhParamBlobLength);
if( NULL == DhParamBlob )
{
Status = STATUS_NO_MEMORY;
ReportError(Status);
goto cleanup;
}
DhParamHdrPointer = (BCRYPT_DH_PARAMETER_HEADER *)DhParamBlob;
//
// Set header properties on param blob
//
DhParamHdrPointer->cbLength = DhParamBlobLength;
DhParamHdrPointer->cbKeyLength = KeyLength/8;//bytes
DhParamHdrPointer->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
//
// Set prime
//
memcpy(DhParamBlob + sizeof(BCRYPT_DH_PARAMETER_HEADER),
OakleyGroup1P,
sizeof(OakleyGroup1P));
//
// Set generator
//
memcpy(DhParamBlob + sizeof(BCRYPT_DH_PARAMETER_HEADER) + sizeof(OakleyGroup1P),
OakleyGroup1G,
sizeof(OakleyGroup1G));
//
// Open alg provider handle
//
Status = BCryptOpenAlgorithmProvider(
&ExchAlgHandleB,
BCRYPT_DH_ALGORITHM,
NULL,
0);
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// B generates a private key
//
Status = BCryptGenerateKeyPair(
ExchAlgHandleB, // Algorithm handle
&PrivKeyHandleB, // Key handle - will be created
KeyLength, // Length of the key - in bits
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
Status = BCryptSetProperty(
PrivKeyHandleB,
BCRYPT_DH_PARAMETERS,
DhParamBlob,
DhParamBlobLength,
0);
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
Status = BCryptFinalizeKeyPair(
PrivKeyHandleB, // Key handle
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// B exports DH public key
//
Status = BCryptExportKey(
PrivKeyHandleB, // Handle of the key to export
NULL, // Handle of the key used to wrap the exported key
BCRYPT_DH_PUBLIC_BLOB, // Blob type (null terminated unicode string)
NULL, // Buffer that recieves the key blob
0, // Buffer length (in bytes)
&PubBlobLengthB, // Number of bytes copied to the buffer
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
PubBlobB = (PBYTE)HeapAlloc (
GetProcessHeap (),
0,
PubBlobLengthB);
if( NULL == PubBlobB )
{
Status = STATUS_NO_MEMORY;
ReportError(Status);
goto cleanup;
}
Status = BCryptExportKey(
PrivKeyHandleB, // Handle of the key to export
NULL, // Handle of the key used to wrap the exported key
BCRYPT_DH_PUBLIC_BLOB, // Blob type (null terminated unicode string)
PubBlobB, // Buffer that recieves the key blob
PubBlobLengthB, // Buffer length (in bytes)
&PubBlobLengthB, // Number of bytes copied to the buffer
0); // Flags
if( !NT_SUCCESS(Status) )
{
ReportError(Status);
goto cleanup;
}
//
// Build KDF parameter list
//
//specify hash algorithm, SHA1 if null
//specify secret to append
BufferArray[0].BufferType = KDF_TLS_PRF_SEED;
BufferArray[0].cbBuffer = sizeof(rgbrgbTlsSeed);
BufferArray[0].pvBuffer = (PVOID)rgbrgbTlsSeed;
//specify secret to prepend
BufferArray[1].BufferType = KDF_TLS_PRF_LABEL;
BufferArray[1].cbBuffer = (DWORD)((wcslen(Label) + 1) * sizeof(WCHAR));
BufferArray[1].pvBuffer = (PVOID)Label;
ParameterList.cBuffers = 2;
ParameterList.pBuffers = BufferArray;
ParameterList.ulVersion = BCRYPTBUFFER_VERSION;
//
// B imports A's public key
//
// dh public key blob structure
PBCRYPT_DH_KEY_BLOB p_dh_pub_key_blob = (PBCRYPT_DH_KEY_BLOB)HeapAlloc(
GetProcessHeap(),
0,
sizeof(BCRYPT_DH_KEY_BLOB));
p_dh_pub_key_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
p_dh_pub_key_blob->cbKey = sz/8;
DWORD df_pub_key_data_length = sizeof(BCRYPT_DH_KEY_BLOB) + sz / 8;
PBYTE p_df_pub_key_data = (PBYTE)HeapAlloc(
GetProcessHeap(),
0,
df_pub_key_data_length);
memcpy(p_df_pub_key_data,
p_dh_pub_key_blob,
sizeof(BCRYPT_DH_KEY_BLOB));
memcpy(p_df_pub_key_data + sizeof(BCRYPT_DH_KEY_BLOB),
PubBlobA2,
sz/8);
Status = BCryptImportKeyPair(
ExchAlgHandleB, // Alg handle
NULL, // Parameter not used
BCRYPT_DH_PUBLIC_BLOB, // Blob type (Null terminated unicode string)
&PubKeyHandleB, // Key handle that will be recieved
p_df_pub_key_data, // Buffer than points to the key blob
df_pub_key_data_length, // Buffer length in bytes
0);