【问题标题】:WinAPI -> CryptoAPI -> RSA, encrypt with private, decrypt with publicWinAPI -> CryptoAPI -> RSA,用私有加密,用公共解密
【发布时间】:2012-06-11 16:31:14
【问题描述】:

美好的一天。

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

现在如何运作:

我了解上下文

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 能以某种方式支持这个功能。

【问题讨论】:

    标签: delphi winapi encryption cryptography cryptoapi


    【解决方案1】:

    严格来说,当“签名”一条消息时:

    • 拥有私钥的人用他们的private密钥解密散列。
    • 然后他们将 “解密” 哈希与消息一起发送。
    • 然后接收方使用公钥加密签名

    如果“加密” 散列与原始消息的散列匹配,则您知道该消息没有被更改,并且是由使用私钥的人发送的。以下伪代码表示签名算法:

    //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 的调用留作练习 - 因为我仍在尝试找出 Microsoft 的 Crypto API。

    【讨论】:

      【解决方案2】:

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

      如果您想验证数据没有被更改,您需要对数据进行签名。签名使用私钥加密数据的散列。查看签名函数。

      您也许可以欺骗签名功能来做您想做的事。我已经使用其他实现来完成此操作,但我没有尝试使用 Microsoft CryptoAPI。

      另外,请注意,使用 RSA 加密,纯文本消息不能长于密钥。因此,如果您使用 2048 位密钥,则最多只能加密 256 字节的消息正文(减去一些开销)。

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

      更新

      您也许可以为此使用CryptSignHash() 函数。通常,这用于“签名”哈希,但您可以将任何您想要的数据放入哈希中:

      通过使用HP_HASHVAL 值在散列对象中设置散列值 CryptSetHashParam中的dwParam参数。

      如果输入预期为 SHA1 哈希值,您可能会被限制为这么多字节。

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

      另外,我使用旧(免费软件)版本的 SecureBlackbox 完成了同样的事情。您也许可以找到旧的免费版本,但它对 Unicode 不友好,因此如果您使用新的 Delphi,您将需要进行一些转换。我以前也做过,所以不太难。

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

      否则,如您所说,对其进行签名以检测篡改,并使用只有程序知道的对称密钥对其进行加密以对其进行混淆。

      如果他们破解了你的密码,无论如何都是公平的游戏。

      【讨论】:

        猜你喜欢
        • 2011-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2020-02-28
        • 1970-01-01
        相关资源
        最近更新 更多