使用公钥解密

huangapple go评论93阅读模式
英文:

decrypt with public key

问题

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

$ openssl genrsa -out ./server/server.key
生成2048位长模数的RSA私钥
..................+++
.............................................+++

$ openssl rsa -in ./server/server.key -pubout -out ./client/client.pub
写入RSA密钥

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

# 使用公钥解密
$ openssl rsautl -inkey ./client/client.pub -pubin -in ./secret
secret
英文:

How can I decrypt a message signed with a private key in 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

答案1

得分: 5

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

我没有找到任何纯Go语言的实现。这是一个使用cgo的实现:https://github.com/dgkang/rsa/blob/master/rsa/rsa.go

更新,对我有用的代码如下:

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:]
}

以上是翻译好的内容,请确认是否满意。

英文:

I fully understood my question, it was about RSA_public_decrypt method of openssl: https://www.openssl.org/docs/man1.1.0/crypto/RSA_public_decrypt.html

I did not found any pure-golang realization. Realization with cgo: https://github.com/dgkang/rsa/blob/master/rsa/rsa.go

UPD, work for me:

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 &lt; len(out); i++ {
        if i+1 &gt;= len(out) {
            break
        }
        if out[i] == 0xff &amp;&amp; out[i+1] == 0 {
            skip = i + 2
            break
        }
    }
    return out[skip:]
}

答案2

得分: 2

我认为这里有一些误解。openssl rsautl -sign并不是用来加密数据的,它生成的是一个签名。你的secret文件中的内容并不是加密的"secret",而是使用私钥对文本"secret"进行签名的结果。

使用公钥,你可以使用-verify选项来验证签名,但这似乎不是你想要做的。听起来你想要的是加密/解密,而不是签名/验证。

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

请记住,使用RSA加密的数据量是有限制的。通常情况下,你会使用RSA来保护对称密钥,并使用对称密钥进行大量的加密和解密操作。

英文:

I think there is a bit of a misunderstanding here. openssl rsautl -sign does not encrypt the data. It produces a signature. The contents in your secret file is not "secret", encrypted. Rather, it is a signature of the text "secret" that is signed with the private key.

Using the public key, you can -verify the signature, but this isn't really what you are trying to do. It sounds like you want encrypt/decrypt, not sign/verify.

Use the -encrypt and -decrypt options of rsautl. Encryption happens with the public key, and decryption happens with the private key.

Keep in mind there are limits to the amount of data you can encrypt with RSA. Typically, you would protect a symmetric key with RSA, and use the symmetric key to do bulk encryption and decryption.

huangapple
  • 本文由 发表于 2017年7月1日 01:48:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/44852289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定