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

Encryption 如何在WinCrypt中生成和使用公钥密码,encryption,cryptography,cryptoapi,public-key-encryption,Encryption,Cryptography,Cryptoapi,Public Key Encryption,我目前正在试验Windows加密API,在公钥加密方面遇到了一些问题。我可以找到很多关于如何加密项的示例,但没有直接解决从开始到结束的公钥模型 下面是我当前代码生成加密密钥对的大致轮廓,我已经删除了可读性错误检查代码 // MAKE AN RSA PUBLIC/PRIVATE KEY: CryptGenKey(hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &hKey); // NOW LET'S EXPORT THE PUBLIC KEY: D

我目前正在试验Windows加密API,在公钥加密方面遇到了一些问题。我可以找到很多关于如何加密项的示例,但没有直接解决从开始到结束的公钥模型

下面是我当前代码生成加密密钥对的大致轮廓,我已经删除了可读性错误检查代码

// 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();
我的两个导出密钥不同,但都能够在不加载另一个密钥的情况下解密消息。此外,如果我在加载导出公钥的新会话中加密新消息,我仍然可以使用任意一个密钥对其解密


有谁能告诉我我可能做错了什么或错过了什么?我是否完全走错了路?

我不完全理解您的疑问。但总的来说

  • 您不能直接使用公钥加密数据

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

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


  • 我还不是这方面的专家呢!但我现在正在处理这件事,所以我能感觉到你的痛苦

    加密位似乎有问题

    // 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”,以便它可以计算出大小并为您返回它!然后你就可以继续剩下的了。。我知道导出位就是这样工作的(因为您在该上下文中使用键),而这里您处理的是实际的消息。尝试传入参数,看看结果如何

    我想你会发现你不能用两个密钥解密,因为你还没有真正加密任何东西????我想是你把信息加密到了一个零大小的缓冲区


    正如我所说,我不是专家,但我觉得这是不对的。。。最奇怪的是,前几天我发现了你的帖子,并收集了一些有用的信息来帮助我理解它,所以我真的希望这些信息能帮助你

    浏览以下由microsoft提供的链接


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

    重新评论一:我不太理解这句话——我想用公钥和私钥进行加密(传统上,你用公钥加密以发送“给”密钥所有者,用私钥加密以“签名”密钥所有者)。至于#2/#3,这很好,但有点不相关——我想要对密钥的原始访问,我不是在标准消息交换中使用加密,而是在利用公共/私有加密的其他方面。重点仍然是——为什么我不能用任意一个公钥/私钥正确解密?@Tom,下面的帖子可能会有所帮助,嗨,LeeC,好问题。这是一种常见的microsoft模式,下面是MSDN中的相关文档行:如果pbData为NULL,则不会返回错误,函数将数据大小(以字节为单位)存储在指向pdwDataLen的变量中。这使应用程序可以明确地确定正确的缓冲区大小。-嗨,汤姆,我现在同意了!您正试图根据提供者等(在获取上下文位中选择)确定缓冲区的实际大小。因此,这意味着无论原始消息是什么,所有加密块的大小都相同,但取决于提供程序。对不起,我帮不上忙!老实说,我希望我从来没有这样开始过-我有一个任务到期,我将从服务器传递到客户端的公钥-客户端加密消息并返回到服务器-但公钥只是不能很好地发挥!祝我们大家好运!LeeC,为了解决这个问题,我最终放弃了,选择了CryptoPP----如果你可以选择的话,它会更有用。谢谢Tom,我一定会看看的。我只是担心我太过分了,不能重新开始。我想,当消息在调试器中以类似“-”的形式被提交,然后被解密回原始状态时,我已经对其进行了加密—导出的公钥在服务器上导入时再次起作用,但在传输到客户端之后或之前,会出现一些问题。在客户端导入中,它给出了错误的提供程序错误-但看起来一切正常,所以我不知道。我一定读过谷歌上的所有内容,但仍然没有解决方案。也许是时候我请求一些帮助了。。。无论如何,再次感谢。嗨,汤姆,我回来了,我想我现在知道你的代码有什么问题了!发布的代码是否高于您用于实现目标的实际代码?