1

I'm trying to make simple working example of encryption and decryption with BCrypt but I'm can't get it to work because I don't understand exactly how. From BCryptEncrypt Function, Microsoft Docs:

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

I generated a simple 512bit key pair on 8gwifi.org:

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";

To be honest I don't understand exactly how to use this function for this situation, I tried searching a simple example but couldn't find any.

Thank you.

1 Answers1

7

There is an sample here: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/007a0e26-7fc0-4079-9b63-2ad23f866836/bug-in-rsa-encryptiondecryption-using-cng?forum=windowssdk

Please note that the first byte of encrypted data should not exceed 0xb6. And there is a detailed explanation in the post.

Take encryption as an example, First, use BCryptOpenAlgorithmProvider to load and initialize a CNG provider that specify RSA.

#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;
}

Then, 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;
}

To get Encrypted Buffer Size:

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;
}

Encrypte Data:

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);
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
  • 1
    You can change BCryptEncrypt‘s last argument as BCRYPT_PAD_PKCS1. That is better to find where is important. – qux Dec 04 '22 at 02:08
  • See https://github.com/Azure/azure-c-shared-utility/blob/4f1b7cd6bf48833fe4b9e23e2ff07510753faee5/adapters/x509_schannel.c for a complete example of how to import keys from PEM files/data. – Michael Mueller Dec 05 '22 at 21:50