Search code examples
c++winapirsacng

How to use BCrypt for RSA (asymmetric encryption)


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.


Solution

  • 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);