如何在C/C++中获取RSA公钥的模和指数



我正在使用BCrypt Windows库来处理我的应用程序中的RSA算法。

问题:我需要获取RSA公钥模数和指数。

在C#语言中,我使用RSACryptoProvider类来获取这些信息(ExportParameters方法(。

在我的C/C++应用程序中,BCrypt似乎无法获取正确的数据。。。

到目前为止我所做的:

BOOL RSA_New(RSA_CTX_ST* rsa_ctx, const BYTE key_data[256], DWORD key_len, BOOL cipher)
{
if (rsa_ctx == NULL || key_len != RSA_2048_BLOCK_SIZE)
{
return FALSE;
}
NTSTATUS status = STATUS_UNSUCCESSFUL;
BCRYPT_ALG_HANDLE* algo_handle = NULL;
BCRYPT_KEY_HANDLE* key_handle = NULL;
algo_handle = malloc(sizeof(BCRYPT_ALG_HANDLE));
key_handle = malloc(sizeof(BCRYPT_KEY_HANDLE));
if (algo_handle == NULL || key_handle == NULL) goto END;
//Creation handle Algo
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(algo_handle, BCRYPT_RSA_ALGORITHM, NULL, 0)))
{
UTL_Trace("SEC", VRB_MAJOR, "RSA:Algorithm handle opening error");
if (status == STATUS_INVALID_HANDLE)
{
UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
}
if (status == STATUS_INVALID_PARAMETER)
{
UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
}
goto END;
}
// Key pair generation
if (!NT_SUCCESS(status = BCryptGenerateKeyPair(algo_handle, key_handle, 2048, 0)))
{
UTL_Trace("SEC", VRB_MAJOR, "RSA:Key pair generating error");
if (status == STATUS_INVALID_HANDLE)
{
UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
}
if (status == STATUS_INVALID_PARAMETER)
{
UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
}
goto END;
}
BCRYPT_RSAKEY_BLOB my_rsa_blob;
ULONG* pcbResult = NULL;
pcbResult = calloc(1, sizeof(ULONG));
if (pcbResult == NULL)
{
UTL_Trace("SEC", VRB_INFO, "Allocating RSA result error");
goto END;
}
// Export parameters of keys
if (!NT_SUCCESS(status = BCryptExportKey(key_handle, NULL, BCRYPT_RSAFULLPRIVATE_BLOB, &my_rsa_blob, sizeof(my_rsa_blob), pcbResult, 0)))
{
UTL_Trace("SEC", VRB_MAJOR, "RSA:Key pair exporting error");
if (status == STATUS_INVALID_HANDLE)
{
UTL_Trace("SEC", VRB_INFO, "INVALID HANDLE");
}
if (status == STATUS_INVALID_PARAMETER)
{
UTL_Trace("SEC", VRB_INFO, "INVALID PARAMS");
}
goto END;
}
return TRUE;
END:
if (algo_handle != NULL) free(algo_handle);
if (key_handle != NULL) free(key_handle);
return FALSE;
}

在my_rsa_blob中,我应该有模和指数的大小,但不是它们的值。。。

有人能解决这个问题吗?

事实上,我确实找到了解决方案!

通过调用BCryptExportKey,变量my_rsa_blob应该是一个PUCHAR变量,它是一个指向字符串的指针。

有了这个,我在搜索时在Microsoft文档中找到了一个链接。。。链接显示PUCHAR变量是如何设计的:

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/540b7b8b-2232-45c8-9d7c-af7a5d5218ed

之后,您可以尝试这样操作数据:

static BOOL RSA_RecoverKeyInformation(RSA_CTX_ST* rsa_ctx, PUCHAR ptrKey)
{
strncpy(rsa_ctx->key_information.header.Magic, ptrKey[0], 4);
strncpy(rsa_ctx->key_information.header.BitLength, ptrKey[1 * 4], 4);
strncpy(rsa_ctx->key_information.header.cbPublicExp, ptrKey[2 * 4], 4);
strncpy(rsa_ctx->key_information.header.cbModulus, ptrKey[3 * 4], 4);
strncpy(rsa_ctx->key_information.header.cbPrime1, ptrKey[4 * 4], 4);
strncpy(rsa_ctx->key_information.header.cbPrime2, ptrKey[5 * 4], 4);
size_t sizeOfModulus = rsa_ctx->key_information.header.cbModulus;
size_t sizeOfExponent = rsa_ctx->key_information.header.cbPublicExp;
rsa_ctx->key_information.keyExponent = malloc(sizeOfExponent);
rsa_ctx->key_information.keyModulus = malloc(sizeOfModulus);
if (rsa_ctx->key_information.keyExponent == NULL || rsa_ctx->key_information.keyModulus == NULL) goto END;
strncpy(rsa_ctx->key_information.keyExponent, ptrKey[6 * 4], sizeOfExponent);
strncpy(rsa_ctx->key_information.keyModulus, ptrKey[6 * 4 + sizeOfExponent], sizeOfModulus);
return TRUE;
END:
if (rsa_ctx->key_information.keyExponent != NULL) free(rsa_ctx->key_information.keyExponent);
if (rsa_ctx->key_information.keyModulus != NULL) free(rsa_ctx->key_information.keyModulus);
return FALSE;
}

最新更新