美好的一天。
我需要教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支持这个功能。
答案 0 :(得分:3)
严格来说,当“签署”消息时:
如果“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并购买它,如果它适合您。
否则,如您所述,将其签名以检测篡改,并使用只有程序知道的对称密钥对其进行加密,以便对其进行模糊处理。
如果他们破解你的代码,无论如何,任何事情都是合理的。