4

我目前正在尝试使用 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

4 回答 4

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, &encryptBufferLen, 0); // 但是为什么当你实际上应该传入包含要加密的字符串的缓冲区时为“NULL”,以便它可以计算出大小并为你返回它!然后你可以继续剩下的。我知道导出位是如何工作的(因为你在那个上下文中使用键),而在这里你正在处理实际的消息。尝试传入参数,看看效果如何?

我想您会发现您实际上无法使用两个密钥进行解密,因为您实际上还没有加密任何东西????我认为您将消息加密到零大小的缓冲区中。

正如我所说的不是专家,但它对我来说确实是错误的......最奇怪的是我前几天发现了你的帖子并收集了一些工作内容来帮助我理解它,所以我真的希望这些信息对你有所帮助!

于 2011-05-04T14:55:14.390 回答
0

我不完全理解您的询问。但一般

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

  2. 加密期间:您使用会话/对称/私钥来加密数据。该会话密钥随后由 AT_EXCHANGE 公钥加密。

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

于 2011-04-15T12:42:11.470 回答
0

您是否在两个键上都使用 CryptImportKey?看起来您的加密只是使用您生成的密钥的句柄。要正确地进行公共/私人对,您应该使用 CryptExportKey 仅导出公共密钥并将其提供给需要它的任何人。虽然这不是真正的“加密”,但它是让那个人知道它来自你的一种方式。

于 2015-07-10T17:52:38.090 回答