使用BCryptImportKeyPair的STATUS_INVALID_PARAMETER错误导入diffie hellman公钥

时间:2017-09-06 18:08:32

标签: c++ winapi cryptoapi cng wincrypt

我正在尝试将公钥添加到Bcrypt的diffie Hellman实现中。 example建议创建并导出公钥。在我的情况下,我已经从客户端获得了公钥。我试图使用该公钥生成共享会话密钥。当我尝试使用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);    

0 个答案:

没有答案