How to generate and use public key cryptography in

2019-07-20 01:15发布

问题:

I'm currently experimenting with the Windows Cryptography API and running into some problems with Public-Key-Cryptography. I can find lots of examples of how to encrypt items, but nothing directly addressing a start-to-finish public key model.

Here's a rough outline of how my current code looks to generate an encryption key pair, I've removed the error checking code for readability

// MAKE AN RSA PUBLIC/PRIVATE KEY:
    CryptGenKey(hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &hKey);

// NOW LET'S EXPORT THE PUBLIC KEY:
    DWORD keylen;
    CryptExportKey(hKey,0,PUBLICKEYBLOB,0,NULL,&keylen);
    LPBYTE KeyBlob;
    KeyBlob = (LPBYTE)malloc(keylen);
    CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,KeyBlob,&keylen);
    ofstream outputkey;
    outputkey.open("TestPublicKey.txt", ios_base::out | ios_base::binary);
    for(size_t i=0; i < keylen; ++i)
        outputkey<<KeyBlob[i];
    outputkey.close();
    free(KeyBlob);

// NOW LET'S EXPORT THE PRIVATE KEY:
    CryptExportKey(hKey, 0, PRIVATEKEYBLOB,0,NULL,&keylen);
    KeyBlob = (LPBYTE)malloc(keylen);
    CryptExportKey(hKey,NULL,PRIVATEKEYBLOB,0,KeyBlob,&keylen)
    outputkey.open("TestPrivateKey.txt", ios_base::out | ios_base::binary);
    for(size_t i=0;i<keylen;++i)
        outputkey<<KeyBlob[i];
    outputkey.close();
    free(KeyBlob);

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]:
    DWORD encryptBufferLen=0;
    CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space?
    BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen);
    memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt
    CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen );

    ofstream message;
    message.open("Message.txt", ios_base::out | ios_base::binary);
    for(size_t i=0;i<encryptBufferLen;++i)
        message<<encryptionBuffer[i];
    message.close();

My two exported keys are different, but both are able to decrypt message without the other key being loaded. Additionally, if I encrypt a new message in a new session that loads the exported public key, I can still decrypt it with either key.

Can anyone advise me on what I might be doing wrong or missing? Am I on completely the wrong path?

回答1:

I do not fully understand your query. But generally

  1. You do not encrypt data directly using a public key.

  2. During Encryption: You use a session/symmetric/private key to encrypt data. This session key is then being encrypted by the AT_EXCHANGE public key.

  3. During Decryption: The AT_EXCHANGE private key will decrypt the session key. In turn this session key will be used to decrypt the actual data.



回答2:

I am not an expert with this encryption stuff just yet! but I am working with this at the moment so can feel your pain...

Something looks amiss with the encrypt bit

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]:
DWORD encryptBufferLen=0;
CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space?
BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen);
memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt
CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen );

It appears that you are asking the function to give you the size of the encrypted message so that you can assign its memory i.e. size... BUT you are not passing anything in apart from the key itself so I dont think it would be able to give that information surely..

You have CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // but why "NULL" when you actually should pass in the buffer containing the string to be encrypted, so that it can work out the size and return it for you! Then you can move on with the rest.. I know thats how the export bit works (because your working with the keys in that context), whereas here you are dealing with the actual message. Try passing in the parameter and see how that goes?

I think you'll find that your not actually able to decrypt with both keys, as you haven't actually encrypted anything yet???? Your encrypting a message into a zero sized buffer I think.

As I said not an expert but it does look wrong to me... Strangest thing is I found your post the other day and harvested the working bits to help me understand it, so I really hope that this info helps you!



回答3:

Go through the links below provided by microsoft

http://msdn.microsoft.com/en-us/library/windows/desktop/aa382358(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa382044(v=vs.85).aspx



回答4:

Are you using CryptImportKey on both keys? It looks like your encrypt is just using the handle to thekey you generated. To do Public/Private pairs correctly you should export just the public key with CryptExportKey and give it to whomever needs it. Although this isn't true "encryption" its a way for that person to know it is from you.