WinAPI - > CryptoAPI - > RSA,私有加密,公共解密

时间:2012-06-11 16:31:15

标签: delphi winapi encryption cryptography cryptoapi

美好的一天。

我需要教Windows CryptoAPI使用密钥的私有(非公共)部分加密消息,并使用public解密。这对于向用户提供他们可以阅读但无法更改的信息是必要的。

现在如何运作:

我得到了上下文

CryptAcquireContext(@Prov, PAnsiChar(containerName), nil, PROV_RSA_FULL, 0)

生成密钥对

CryptGenKey(Prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, @key)

加密(问题出在这里。“key” - 密钥对,函数使用其公共部分);

CryptEncrypt(key, 0, true, 0, @res[1], @strLen, buffSize)

解密(这里同样的问题,它使用密钥的私有部分)

CryptDecrypt(key, 0, true, 0, @res[1], @buffSize)

感谢您的关注/帮助。

更新

是的,我可以使用数字签名和其他方法......

问题是我需要加密一个数据库字段,并确保除了我之外没有人可以更改它。只有在我的程序的帮助下才能读取该字段(直到某人反编译并获得公钥)。这可以通过对称的密钥和数字签名来完成,但是我需要创建另一个字段并存储另一个密钥等等......

我希望我们能以某种方式教导WIN API按我的意愿去做。我知道我可以使用RSA这样做,我希望不知何故WinAPI支持这个功能。

2 个答案:

答案 0 :(得分:3)

严格来说,当“签署”消息时:

  • 拥有私钥的人使用私有键对哈希进行解密
  • 然后他们发送“decrypted”哈希以及消息。
  • 接收方然后使用公钥加密签名

如果“encrypted”哈希与原始邮件的哈希匹配,则表示邮件未被更改,并且是由具有私钥的人发送的。以下伪代码表示签名算法:

//Person with private key generating message and signature
originalHash = GenerateHashOfMessage(message);
signature = RsaDecrypt(originalHash, privateKey);

//Receiver validating signed message
hash = GenerateHashOfMessage(message);
originalHash = RsaEncrypt(signature, publicKey);
messageValid = (hash == originalHash);

可以使用相同的机制来完成您想要的任务。除非您不关心哈希,否则您只想加密一些(少量)数据:

//Person with private key
cipherText = RsaDecrypt(plainText, privateKey);

//Person with public key
plainText = RsaEncrypt(cipherText, publicKey);

我会将CryptoAPI电话留作练习 - 因为我还在试图找出微软的加密API。

答案 1 :(得分:2)

不支持使用私钥加密数据并使用公钥对其进行解密,因为拥有“已发布”公钥的任何人都可以对其进行解密。加密它的价值是什么?

如果要验证数据是否未更改,则需要对数据进行签名。签名使用私钥加密数据的散列。看看签名功能。

您可以欺骗签名功能以执行您想要的操作。我已经完成了其他实现,但我还没有尝试使用Microsoft CryptoAPI。

另请注意,使用RSA加密时,纯文本邮件不能超过密钥。因此,如果您使用的是2048位密钥,则只能加密最多256个字节的消息体(减少一些用于开销)。

考虑使用非对称加密仅传递对称密钥,并使用对称密钥加密和解密任何大小的数据。

<强>更新

您可以使用CryptSignHash()功能。通常,这用于“签名”哈希,但您可以将所需的任何数据放入哈希:

  

使用HP_HASHVAL值设置哈希对象中的哈希值   CryptSetHashParam中的dwParam参数。

如果输入应该是SHA1哈希值,则可能限制为这么多字节。

或者,您可能希望考虑使用OpenSSL。如果我没记错的话,使用其RSA signing函数来加密私钥是非常简单的。

另外,我使用旧的(免费软件)版本的SecureBlackbox完成了同样的事情。您可能能够找到旧的免费版本,但它不是Unicode友好的,所以如果您使用新的Delphi,您将进行一些转换。我过去也做过这个,所以这并不太难。

您也可以考虑尝试使用当前的SecureBlackbox并购买它,如果它适合您。

否则,如您所述,将其签名以检测篡改,并使用只有程序知道的对称密钥对其进行加密,以便对其进行模糊处理。

如果他们破解你的代码,无论如何,任何事情都是合理的。