如何使用RSA私钥解密加密的消息

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

How to decrypt an encrypted message with RSA private key

问题

我正在使用一个需要我的公钥的API,然后该API将返回一个包含向量和令牌的响应,但它们是以加密形式存在的(我认为他们使用了我的公钥来进行加密)。为了解密它,我需要使用我的私钥。私钥和公钥都以DER编码形式存在。
我基本上想要实现类似于这个网站的功能:https://www.devglan.com/online-tools/rsa-encryption-decryption

我正在使用的密钥(它们只是示例):
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbI1SofN/ZPsprBlPAW/c4GDKHo6Idv3J/P5LEEUpAsbVVpq6wY7Tf6lfBSTcirq48oMD34p3z5sX1jYy15OXNxNKBpoOdv8BYQdnK/LfFcZ5720yUNka0xiHUol/Zi0c0PWB6HkAAkT0sbeGLbCuX6yr6SbJBFaI2ofIKk/mGswIDAQAB
私钥:MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJsjVKh839k+ymsGU8Bb9zgYMoejoh2/cn8/ksQRSkCxtVWmrrBjtN/qV8FJNyKurjygwPfinfPmxfWNjLXk5c3E0oGmg52/wFhB2cr8t8VxnnvbTJQ2RrTGIdSiX9mLRzQ9YHoeQACRPSxt4YtsK5frKvpJskEVojah8gqT+YazAgMBAAECgYA5KaeD/Z8tmSlUjhxGAJzzGldkCzMs6uHxaSdW/1fwxooeaTBs5hA7gUmcerHKIbsps8HmlKXGvP2sIN/8Fb9mo1yHaAN2g52+cvpr2QmeeUOwfuZTM/gllT4rUIB7sMC5Uxl7sW55bGhRxqdfHJskow4rPga+irjuYSy5GIZSwQJBANDtfF+VWPKrR8MHYvaGoLLkrA1cFn8g9x1eGA3mgWPNYoH5nMJfe0IBaXo69jlrnBAjK+oxnPSyh/AZzsEehasCQQC+F15dVSjH8tJSXz8RCDpMdp+P9J/eoi7+V0IgwKAaSJCZfYWXeckAAIpvwit7fkj3n83nj0PPm9Xwh22CYGsZAkAAvIWOtLEOken71v/TTKAuYT32AhgWNKCKWvWMvv4/ws6RFLcnvDxr/CNKCgEqLKXtLKKP/cLG3gY6o2ymI5xnAkA8l4JSycRYB8SW0RlvOmoq2Vz/LACRnKzSEcpYWk4uUpcU9ffRUtaJE6MNAJ2Pna9wjxW5C+eXk5rcMq7rcgRxAkAjizE3JbwUu3MX5TDmHfGCvIZ38jnfSUjFrYBLKaNJegOD4zcxRZXfO7iKDa+PtFMRe7ZtnU7WuCM0yUT2Qa0j
加密消息:BUy5nR/PuJNCFXeUxQd4oxkCvMo2JiLwH5VkzLz1UdM4M0VXDv4Ba1OaNHbttqETQENy1VfW2V4v9Pw5HmDIcS1sdGN69ceEHJbned46rK1EVtMVQZGP9ha54AXie5v/1TdKYWJ+AFt0FxVj4kfFXGXEzF19Q8LB2AOJCAEJK6s=
现在让我们来看看代码部分:
我正在从环境文件中获取我的私钥和公钥:

public := goDotEnvVariable("publicKey")
private := goDotEnvVariable("privateKey")

在调用API并获取结果后,我尝试使用rsa.DecryptOAEP函数解密消息,但它一直给我返回[] crypto/rsa: decryption error。在包内部进行调试后,我发现错误出现在这里:

k := priv.Size() // 私钥的大小
if len(ciphertext) > k || // ciphertext 是加密的文本,hash.Size()*2+2 是我使用的哈希大小
	k < hash.Size()*2+2 {
	return nil, ErrDecryption
}

if语句的结果:k = 128,hash.Size()*2+2 = 66,cipher = 172
起初,我遇到了将私钥(在我的情况下是字符串,因为它来自环境文件)转换为RSA私钥的问题。以下是我解决问题的方法:

sEnc, err := b64.StdEncoding.DecodeString(private) // 使用这个包 "encoding/base64" 进行解码

然后我进行了如下转换:

block := &pem.Block{
	Type:  "RSA PRIVATE KEY",
	Bytes: sEnc,
}
parseResult, err := x509.ParsePKCS8PrivateKey(block.Bytes)

我做错了什么?

英文:

I'm hitting an API that requires my public key, then that API will return a response that contains a vector and a token but they are in an encrypted form (I think they used my public key to do that). In order to decrypt it, I need to use my private key. Both private and public keys are in DER encoding.
I basically want to implement something like this https://www.devglan.com/online-tools/rsa-encryption-decryption
如何使用RSA私钥解密加密的消息

Keys that Im using (again they are dummy!)
Public: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbI1SofN/ZPsprBlPAW/c4GDKHo6Idv3J/P5LEEUpAsbVVpq6wY7Tf6lfBSTcirq48oMD34p3z5sX1jYy15OXNxNKBpoOdv8BYQdnK/LfFcZ5720yUNka0xiHUol/Zi0c0PWB6HkAAkT0sbeGLbCuX6yr6SbJBFaI2ofIKk/mGswIDAQAB

Private: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJsjVKh839k+ymsGU8Bb9zgYMoejoh2/cn8/ksQRSkCxtVWmrrBjtN/qV8FJNyKurjygwPfinfPmxfWNjLXk5c3E0oGmg52/wFhB2cr8t8VxnnvbTJQ2RrTGIdSiX9mLRzQ9YHoeQACRPSxt4YtsK5frKvpJskEVojah8gqT+YazAgMBAAECgYA5KaeD/Z8tmSlUjhxGAJzzGldkCzMs6uHxaSdW/1fwxooeaTBs5hA7gUmcerHKIbsps8HmlKXGvP2sIN/8Fb9mo1yHaAN2g52+cvpr2QmeeUOwfuZTM/gllT4rUIB7sMC5Uxl7sW55bGhRxqdfHJskow4rPga+irjuYSy5GIZSwQJBANDtfF+VWPKrR8MHYvaGoLLkrA1cFn8g9x1eGA3mgWPNYoH5nMJfe0IBaXo69jlrnBAjK+oxnPSyh/AZzsEehasCQQC+F15dVSjH8tJSXz8RCDpMdp+P9J/eoi7+V0IgwKAaSJCZfYWXeckAAIpvwit7fkj3n83nj0PPm9Xwh22CYGsZAkAAvIWOtLEOken71v/TTKAuYT32AhgWNKCKWvWMvv4/ws6RFLcnvDxr/CNKCgEqLKXtLKKP/cLG3gY6o2ymI5xnAkA8l4JSycRYB8SW0RlvOmoq2Vz/LACRnKzSEcpYWk4uUpcU9ffRUtaJE6MNAJ2Pna9wjxW5C+eXk5rcMq7rcgRxAkAjizE3JbwUu3MX5TDmHfGCvIZ38jnfSUjFrYBLKaNJegOD4zcxRZXfO7iKDa+PtFMRe7ZtnU7WuCM0yUT2Qa0j

Encrypted message: BUy5nR/PuJNCFXeUxQd4oxkCvMo2JiLwH5VkzLz1UdM4M0VXDv4Ba1OaNHbttqETQENy1VfW2V4v9Pw5HmDIcS1sdGN69ceEHJbned46rK1EVtMVQZGP9ha54AXie5v/1TdKYWJ+AFt0FxVj4kfFXGXEzF19Q8LB2AOJCAEJK6s=
Lets go to the coding part:
I'm retrieving my private and public keys from the env file:

public := goDotEnvVariable(&quot;publicKey&quot;)
private := goDotEnvVariable(&quot;privateKey&quot;)

Now after hitting the API and getting the result, I tried to decrypt the message by using rsa.DecryptOAEPfunction but it keeps giving me [] crypto/rsa: decryption error. After debugging inside the package itself, Im getting the error right here:

k := priv.Size() // private key size
if len(ciphertext) &gt; k || //ciphertext is the encrypted text and hash.Size()*2+2 is the hash size that Im using
	k &lt; hash.Size()*2+2 {
	return nil, ErrDecryption
}

Results of the if statement: k = 128 hash.Size()*2+2=66 cipher = 172
At first I had a problem of converting the private key (string in my case, because its from the env file) to rsa private key.
Heres what I did to solve the issue:

	sEnc, err := b64.StdEncoding.DecodeString(private) //using this package &quot;encoding/base64&quot;

Then I converted it like this:

	block := &amp;pem.Block{
	Type:  &quot;RSA PRIVATE KEY&quot;,
	Bytes: sEnc,
    }
    parseResult, err := x509.ParsePKCS8PrivateKey(block.Bytes)

What am I doing wrong?

答案1

得分: 1

如果在"选择密码类型"字段中选择了RSA,则devglan网站将应用PKCS#1 v1.5作为填充方式,因此必须使用rsa.DecryptPKCS1v15()。私钥是Base64编码的PKCS#8 DER密钥,可以使用x509.ParsePKCS8PrivateKey()导入。

完整代码如下:

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	b64 "encoding/base64"
	"fmt"
)

func main() {

	// Base64解码密文
	ciphertext, _ := b64.StdEncoding.DecodeString("BUy5nR/PuJNCFXeUxQd4oxkCvMo2JiLwH5VkzLz1UdM4M0VXDv4Ba1OaNHbttqETQENy1VfW2V4v9Pw5HmDIcS1sdGN69ceEHJbned46rK1EVtMVQZGP9ha54AXie5v/1TdKYWJ+AFt0FxVj4kfFXGXEzF19Q8LB2AOJCAEJK6s=")

	// 导入PKCS#8密钥
	pkcs8DerKey, _ := b64.StdEncoding.DecodeString("MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJsjVKh839k+ymsGU8Bb9zgYMoejoh2/cn8/ksQRSkCxtVWmrrBjtN/qV8FJNyKurjygwPfinfPmxfWNjLXk5c3E0oGmg52/wFhB2cr8t8VxnnvbTJQ2RrTGIdSiX9mLRzQ9YHoeQACRPSxt4YtsK5frKvpJskEVojah8gqT+YazAgMBAAECgYA5KaeD/Z8tmSlUjhxGAJzzGldkCzMs6uHxaSdW/1fwxooeaTBs5hA7gUmcerHKIbsps8HmlKXGvP2sIN/8Fb9mo1yHaAN2g52+cvpr2QmeeUOwfuZTM/gllT4rUIB7sMC5Uxl7sW55bGhRxqdfHJskow4rPga+irjuYSy5GIZSwQJBANDtfF+VWPKrR8MHYvaGoLLkrA1cFn8g9x1eGA3mgWPNYoH5nMJfe0IBaXo69jlrnBAjK+oxnPSyh/AZzsEehasCQQC+F15dVSjH8tJSXz8RCDpMdp+P9J/eoi7+V0IgwKAaSJCZfYWXeckAAIpvwit7fkj3n83nj0PPm9Xwh22CYGsZAkAAvIWOtLEOken71v/TTKAuYT32AhgWNKCKWvWMvv4/ws6RFLcnvDxr/CNKCgEqLKXtLKKP/cLG3gY6o2ymI5xnAkA8l4JSycRYB8SW0RlvOmoq2Vz/LACRnKzSEcpYWk4uUpcU9ffRUtaJE6MNAJ2Pna9wjxW5C+eXk5rcMq7rcgRxAkAjizE3JbwUu3MX5TDmHfGCvIZ38jnfSUjFrYBLKaNJegOD4zcxRZXfO7iKDa+PtFMRe7ZtnU7WuCM0yUT2Qa0j")
	key, _ := x509.ParsePKCS8PrivateKey(pkcs8DerKey)
	var privateKey *rsa.PrivateKey
	privateKey, _ = key.(*rsa.PrivateKey)

	// 解密(使用带有PKCS#1 v1.5填充的RSA)
	rng := rand.Reader
	plaintext, _ := rsa.DecryptPKCS1v15(rng, privateKey, ciphertext)

	fmt.Println(string(plaintext)) // {"token":"312ade4b52e7bb4cadf59b4c7c83cb41","vector":"2b8db4fdb11f361d","id":"63876cf63ec7a641db8f1def";}
}
英文:

If RSA is selected in the Select Cipher Type field, the devglan website applies PKCS#1 v1.5 as padding, so rsa.DecryptPKCS1v15() must be used. The private key is a Base64 encoded PKCS#8 DER key which can be imported with x509.ParsePKCS8PrivateKey().

All together:

import (
	&quot;crypto/rand&quot;
	&quot;crypto/rsa&quot;
	&quot;crypto/x509&quot;
	b64 &quot;encoding/base64&quot;
	&quot;fmt&quot;
)

func main() {

	// Base64 decode ciphertext
	ciphertext, _ := b64.StdEncoding.DecodeString(&quot;BUy5nR/PuJNCFXeUxQd4oxkCvMo2JiLwH5VkzLz1UdM4M0VXDv4Ba1OaNHbttqETQENy1VfW2V4v9Pw5HmDIcS1sdGN69ceEHJbned46rK1EVtMVQZGP9ha54AXie5v/1TdKYWJ+AFt0FxVj4kfFXGXEzF19Q8LB2AOJCAEJK6s=&quot;)

	// Import PKCS#8 key
	pkcs8DerKey, _ := b64.StdEncoding.DecodeString(&quot;MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJsjVKh839k+ymsGU8Bb9zgYMoejoh2/cn8/ksQRSkCxtVWmrrBjtN/qV8FJNyKurjygwPfinfPmxfWNjLXk5c3E0oGmg52/wFhB2cr8t8VxnnvbTJQ2RrTGIdSiX9mLRzQ9YHoeQACRPSxt4YtsK5frKvpJskEVojah8gqT+YazAgMBAAECgYA5KaeD/Z8tmSlUjhxGAJzzGldkCzMs6uHxaSdW/1fwxooeaTBs5hA7gUmcerHKIbsps8HmlKXGvP2sIN/8Fb9mo1yHaAN2g52+cvpr2QmeeUOwfuZTM/gllT4rUIB7sMC5Uxl7sW55bGhRxqdfHJskow4rPga+irjuYSy5GIZSwQJBANDtfF+VWPKrR8MHYvaGoLLkrA1cFn8g9x1eGA3mgWPNYoH5nMJfe0IBaXo69jlrnBAjK+oxnPSyh/AZzsEehasCQQC+F15dVSjH8tJSXz8RCDpMdp+P9J/eoi7+V0IgwKAaSJCZfYWXeckAAIpvwit7fkj3n83nj0PPm9Xwh22CYGsZAkAAvIWOtLEOken71v/TTKAuYT32AhgWNKCKWvWMvv4/ws6RFLcnvDxr/CNKCgEqLKXtLKKP/cLG3gY6o2ymI5xnAkA8l4JSycRYB8SW0RlvOmoq2Vz/LACRnKzSEcpYWk4uUpcU9ffRUtaJE6MNAJ2Pna9wjxW5C+eXk5rcMq7rcgRxAkAjizE3JbwUu3MX5TDmHfGCvIZ38jnfSUjFrYBLKaNJegOD4zcxRZXfO7iKDa+PtFMRe7ZtnU7WuCM0yUT2Qa0j&quot;)
	key, _ := x509.ParsePKCS8PrivateKey(pkcs8DerKey)
	var privateKey *rsa.PrivateKey
	privateKey, _ = key.(*rsa.PrivateKey)

	// Decrypt (using RSA with PKCS#1 v1.5 padding)
	rng := rand.Reader
	plaintext, _ := rsa.DecryptPKCS1v15(rng, privateKey, ciphertext)

	fmt.Println(string(plaintext)) // {&quot;token&quot;:&quot;312ade4b52e7bb4cadf59b4c7c83cb41&quot;,&quot;vector&quot;:&quot;2b8db4fdb11f361d&quot;,&quot;id&quot;:&quot;63876cf63ec7a641db8f1def&quot;}
}

huangapple
  • 本文由 发表于 2022年11月30日 23:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/74630438.html
匿名

发表评论

匿名网友

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

确定