如何使用 BCrypt 进行 RSA(非对称加密)

rob*_*los 3 c++ winapi rsa cng

我正在尝试使用 BCrypt 制作简单的加密和解密工作示例,但我无法让它工作,因为我不明白到底是如何工作的。来自BCryptEncrypt 函数,Microsoft 文档

NTSTATUS BCryptEncrypt(
  BCRYPT_KEY_HANDLE hKey,
  PUCHAR            pbInput,
  ULONG             cbInput,
  VOID              *pPaddingInfo,
  PUCHAR            pbIV,
  ULONG             cbIV,
  PUCHAR            pbOutput,
  ULONG             cbOutput,
  ULONG             *pcbResult,
  ULONG             dwFlags
);
Run Code Online (Sandbox Code Playgroud)

我在8gwifi.org上生成了一个简单的 512 位密钥对:

string Public_Key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJSNbUhCkU9RuY99L8kC2WRJ8TBES3WX1u9wYlANvUFU/h7lU8VNOWI8dNGCQ6UbK2ypHFom+Zm4BaG1zokwcUkCAwEAAQ==";
string Private_Key = "MIIBOgIBAAJBAJSNbUhCkU9RuY99L8kC2WRJ8TBES3WX1u9wYlANvUFU/h7lU8VNOWI8dNGCQ6UbK2ypHFom+Zm4BaG1zokwcUkCAwEAAQJAZ9bwZAl8L5jt//o/E+C0+2Cggt/Ka5nG+bpyTok8GNTyaG+Prmz/QCYdI3VuYdONdfAPm3jLwtbK9wTt1E8HAQIhAM8jg1nwjN9+nhPyFo0F+2o8y47mq1kHnCn+gqAdW8MhAiEAt5gQcCqX2Y5KbmMoqtQ+4RIEHQ8HD+fyGqxWUhVpESkCIEtylQJqgvVZCj0bnakqN6Q/lqlrTZg1FGWbZXrqlqThAiEAilt5v94Jc7Ws2AW4Rw0OmfVGzlNd4hnNNVa88r0Z4gkCIGfFy2H8pGxHxg1GKE2mSZAfpRMyjqeq119S3t/bhqY2";
string Encrypt_Me = "Hello World";
Run Code Online (Sandbox Code Playgroud)

老实说,我不明白如何在这种情况下使用这个函数,我尝试搜索一个简单的例子,但找不到任何例子。

谢谢。

Dra*_*SFT 9

这里有一个示例: https: //social.msdn.microsoft.com/Forums/windowsdesktop/en-US/007a0e26-7fc0-4079-9b63-2ad23f866836/bug-in-rsa-encryptiondecryption-using-cng ?forum= Windows SDK

请注意,加密数据的第一个字节不应超过0xb6。并且帖子里有详细的解释。

以加密为例,首先使用BCryptOpenAlgorithmProvider加载并初始化指定RSA的CNG提供程序。

#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)
status = BCryptOpenAlgorithmProvider(&hAlgorithm,
    BCRYPT_RSA_ALGORITHM,
    NULL,
    0);
if (!NT_SUCCESS(status)) {
    printf("Failed to get algorithm provider..status : %08x\n", status);
    goto cleanup;
}
Run Code Online (Sandbox Code Playgroud)

然后,BCryptImportKeyPair

status = BCryptImportKeyPair(hAlgorithm,
    NULL,
    BCRYPT_RSAPUBLIC_BLOB,
    &hKey,
    PublicKey,
    PublicKeySize,
    BCRYPT_NO_KEY_VALIDATION);
if (!NT_SUCCESS(status)) {
    printf("Failed to import Private key..status : %08x\n", status);
    goto cleanup;
}
Run Code Online (Sandbox Code Playgroud)

要获取加密缓冲区大小:

status = BCryptEncrypt(hKey,
    InputData,
    InputDataSize,
    NULL,
    NULL,
    0,
    NULL,
    0,
    &EncryptedBufferSize,
    0
);
if (!NT_SUCCESS(status)) {
    printf("Failed to get required size of buffer..status : %08x\n", status);
    goto cleanup;
}

encryptedBuffer = (PUCHAR)HeapAlloc(GetProcessHeap(), 0, encryptedBufferSize);
if (encryptedBuffer == NULL) {
    printf("failed to allocate memory for blindedFEKBuffer\n");
    goto cleanup;
}
Run Code Online (Sandbox Code Playgroud)

加密数据:

status = BCryptEncrypt(hKey,
    InputData,
    InputDataSize,
    NULL,
    NULL,
    0,
    encryptedBuffer,
    encryptedBufferSize,
    &encryptedBufferSize,
    0
);

if (!NT_SUCCESS(status)) {
    printf("Failed encrypt data..status : %08x\n", status);
    goto cleanup;
}
cleanup:
if (hKey)
    BCryptDestroyKey(hKey);
if (hAlgorithm)
    BCryptCloseAlgorithmProvider(hAlgorithm, 0);
Run Code Online (Sandbox Code Playgroud)

  • 您可以将 BCryptEncrypt 的最后一个参数更改为 BCRYPT_PAD_PKCS1。最好找到重要的地方。 (2认同)