Search code examples
phpc++winapipublic-key-encryptioncng

Signing data in c++ app using CNG and verifying in php api


I read a lot about asymmetric encryption and still can't understand how is the step by step process to achieve what I need.

What I need:

  1. Create 1 Private and 1 Public key only once.
  2. Include the private key in my C++ app without the user being able to read it (ofc everything can be hacked, but you know what I mean, don't let the user see it in plain text).
  3. Distribute the app.
  4. Then my app, when used, will Hash an string.
  5. Encrypt this hash with the included private key.
  6. Send this signed hash to my api using an http request.
  7. Decrypt the signed hash in my api (php) using my Public Key.

What I don't understand:

Using the example here: Signing Data with CNG I don't get how can I create the keys once then store the private one in my c++ app and the public one in my api (php).

What I achieved

I learned to hash and encrypt/decrypt data using bCrypt but I don't understand what steps I have to do to achieve what I wrote before


Solution

  • You have to change the design. Currently you design has a major security flaw. You got the concepts of the pubkey/prikey correct, but the implementation is incorrect. The private key should be kept private. Currently it is easy to derive the public key, given the private key for a lot of algorithms, but not the other way around. The right design is as follows.

    1. Generate a self-signed certificate. This certificate will contain private and public key
    2. Export the public certificate and embed it as resource/or hardcode it in your application that you are going to distribute
    3. The application will then hash the data to be signed and use the public key from the application resource.
    4. This hashed data is then sent over the http to your server that has the copy of private key.
    5. The server will hash the data and verify the hash with the private key.

    All of the above steps are well documented with samples on MSDN. If you need further help, let me know and I can point it to the articles.

    The above design will make sure that your private key is never in the wild. If you distribute your private key in your application, it will take literally only few minutes to get your private key.

    Storing the public key in the application is just the matter of either hardcoding the key in the application using byte array or putting the certificate in the resource file.

    The private key portion of the key pair should never be hardcoded in any application. The private key should be non exportable and be managed by the operating system only. Windows now has keyguard that uses VSM technology that makes it impossible for even the local administrator to know the private key. The admin can only use it for signing and verifying (and exporting the key, if exporting is enabled) but never be able to look at the private key and misuse it.

    Regarding step by step process.

    1. Create a self-signed certificate. This will generate a certificate with both public and private key in the pfx file.
    2. Import the self-signed certificate in the certificate store. This can be achived by simply double-clicking on the file and following the directions.
    3. Export the public portion of newly imported certificate from by opening the certificate manager.
    4. You can embed this public exported certificate in your application as a resource.
    5. The application can then load the certificate from the resource and use it to sign the hash.
    6. On the server side, if the certificate with private key is not already imported, follow the step 2 to import it.
    7. Server can then use the Apis to verify the signed data using private key.