【问题标题】:decrypt with public key [closed]用公钥解密[关闭]
【发布时间】:2017-12-04 18:11:22
【问题描述】:

如何解密使用 golang 中的私钥签名的消息?

$ openssl genrsa -out ./server/server.key
Generating RSA private key, 2048 bit long modulus
..................+++
.............................................+++

$ openssl rsa -in ./server/server.key -pubout -out ./client/client.pub
writing RSA key

$ echo "secret" | openssl rsautl -inkey ./server/server.key -sign > ./secret

# decrypt with public key
$ openssl rsautl -inkey ./client/client.pub -pubin -in ./secret
secret

【问题讨论】:

  • 您是否尝试过查看文档? godoc.org/crypto/rsa你试过什么不起作用?您没有发布任何与 Go 相关的内容。
  • 这个库不能用公钥解密消息,只能验证方法
  • @vadv 我认为您误解了非对称密钥加密。您使用公钥加密,然后使用私钥解密,正如您从该包中的函数签名中看到的那样 - Encrypt* 函数使用公钥,而 Decrypt* 函数使用私钥。
  • 您似乎也混淆了签名和加密 - 您能澄清这个问题吗?
  • 签名验证的内部工作实际上是用私钥对签名进行解密,然后验证结果的格式,并将数据中的哈希值与签名数据的哈希值进行比较。理论上是可以做到的,一些签名验证的实现实际上确实暴露了解密的内容。

标签: encryption go openssl cryptography


【解决方案1】:

我完全理解我的问题,是关于openssl的RSA_public_decrypt方法:https://www.openssl.org/docs/man1.1.0/crypto/RSA_public_decrypt.html

我没有找到任何纯 golang 实现。用cgo实现:https://github.com/dgkang/rsa/blob/master/rsa/rsa.go

UPD,为我工作:

func RSA_public_decrypt(pubKey *rsa.PublicKey, data []byte) []byte {
    c := new(big.Int)
    m := new(big.Int)
    m.SetBytes(data)
    e := big.NewInt(int64(pubKey.E))
    c.Exp(m, e, pubKey.N)
    out := c.Bytes()
    skip := 0
    for i := 2; i < len(out); i++ {
        if i+1 >= len(out) {
            break
        }
        if out[i] == 0xff && out[i+1] == 0 {
            skip = i + 2
            break
        }
    }
    return out[skip:]
}

【讨论】:

  • 谢谢,这实际上是一个合法的问题,因为 Golang 的 RSA 包 DecryptPKCS1v15 只接受私钥。不知道为什么你得到这么多反对票。
【解决方案2】:

我认为这里有一点误解。 openssl rsautl -sign 不加密数据。它产生一个签名secret 文件中的内容不是“秘密”,是加密的。相反,它是用私钥签名的文本“secret”的签名。

使用公钥,您可以-verify 签名,但这并不是您真正想要做的。听起来您想要加密/解密,而不是签名/验证。

使用rsautl-encrypt-decrypt 选项。使用公钥进行加密,使用私钥进行解密。

请注意,您可以使用 RSA 加密的数据量是有限的。通常,您会使用 RSA 保护对称密钥,并使用对称密钥进行批量加密和解密。

【讨论】:

  • 始终值得一提的是,自己进行这些操作很难正确且容易出错。我建议找到一个工具,它可以自动使用公钥/私钥加密以及对称加密。单独使用原始 RSA / AES 会带来很多错误。
  • 谢谢@vcsjones 我喜欢获取签名的签名消息('secret')的内容,比如在java中import javax.crypto.Cipher;cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, &lt;rsaPublicKey&gt;);cipher.doFinal(&lt;digest&gt;);这个返回'secret'
猜你喜欢
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 2013-08-06
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多