如何在WinCrypt中生成和使用公钥加密

时间:2011-02-02 00:11:12

标签: encryption cryptography cryptoapi public-key-encryption

我目前正在尝试使用Windows Cryptography API并遇到Public-Key-Cryptography的一些问题。我可以找到很多关于如何加密项目的例子,但没有直接解决从开始到完成的公钥模型。

以下是我当前代码生成加密密钥对的概述,我删除了错误检查代码以提高可读性

// 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();

我的两个导出密钥不同,但两者都能够在不加载其他密钥的情况下解密消息。此外,如果我在加载导出的公钥的新会话中加密新邮件,我仍然可以使用任一密钥对其进行解密。

任何人都可以告诉我我可能做错了什么或错过了什么?我完全走错了路吗?

4 个答案:

答案 0 :(得分:0)

我不完全理解您的查询。但一般来说

  1. 您不使用公钥直接加密数据。

  2. 加密期间:使用会话/对称/私钥加密数据。然后,此会话密钥由AT_EXCHANGE公钥加密。

  3. 解密期间:AT_EXCHANGE私钥将解密会话密钥。反过来,此会话密钥将用于解密实际数据。

答案 1 :(得分:0)

我还不是这种加密技术的专家!但是我现在正在处理这个问题,所以可以感受到你的痛苦......

加密位

看起来不对劲
// 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 );

您似乎要求该功能为您提供加密消息的大小,以便您可以分配其内存,即大小......但是您没有传递任何与键本身不同的内容所以我不认为它会能够肯定地提供这些信息..

你有CryptEncrypt(hKey,0,true,0,NULL,&amp; encryptBufferLen,0); //但是为什么“NULL”当你实际应该传入包含要加密的字符串的缓冲区时,它可以计算出大小并为你返回它!然后你可以继续其余的..我知道导出位是如何工作的(因为你在那个环境中使用了键),而在这里你正在处理实际的消息。尝试传入参数,看看情况如何?

我想你会发现你实际上不能用两个密钥解密,因为你还没有加密任何东西????我认为你将消息加密到零大小的缓冲区。

正如我所说的不是专家,但它对我来说确实是错的...最奇怪的是我前几天找到了你的帖子并收获了工作位来帮助我理解它,所以我真的希望这些信息可以帮到你!

答案 2 :(得分:0)

答案 3 :(得分:0)

你在两个键上都使用CryptImportKey吗?看起来你的加密只是使用你生成的密钥的句柄。要正确执行公共/私有对,您应该只使用CryptExportKey导出公钥,并将其提供给任何需要它的人。虽然这不是真的&#34;加密&#34;这个人知道它的方式来自你。