使用 RSA/PEM 文件解密测试消息时出错
Posted
技术标签:
【中文标题】使用 RSA/PEM 文件解密测试消息时出错【英文标题】:Error Decrypting test message with RSA/PEM files 【发布时间】:2020-06-13 03:09:02 【问题描述】:大家好,我目前正在尝试使用以下代码完成三件事。
使用 crypto/rsa 库生成公钥/私钥对。
将公钥和私钥导出到单独的 PEM 文件中,以便在单独的程序中使用。
将 PEM 文件分别加载到它们各自的脚本中以对消息进行编码/解码。
在我尝试使用“Private-key-decryption.go”解密测试消息之前,一切正常。解密密文时收到此错误“解密错误:crypto/rsa:解密错误”
包括我正在使用的所有代码块
密钥生成.go
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
//Write_private_key_to_file write pem_key to a file
func WriteToFile(Pem_Key string, filename string)
f, err := os.Create(filename)
if err != nil
fmt.Println(err)
return
l, err := f.WriteString(Pem_Key)
if err != nil
fmt.Println(err)
f.Close()
return
fmt.Println(l, "bytes written successfully")
err = f.Close()
if err != nil
fmt.Println(err)
return
//ExportRsaPrivateKeyAsPemStr returns private pem key
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string
privkey_bytes := x509.MarshalPKCS1PrivateKey(privkey)
privkey_pem := pem.EncodeToMemory(
&pem.Block
Type: "RSA PRIVATE KEY",
Bytes: privkey_bytes,
,
)
return string(privkey_pem)
//ExportRsaPublicKeyAsPemStr_to_pem_file extracts public key from generated private key
func ExportRsaPublicKeyAsPemStr(publickey *rsa.PublicKey) (string, error)
pubkey_bytes, err := x509.MarshalPKIXPublicKey(publickey)
if err != nil
return "", err
//fmt.Println(pubkey_bytes)
pubkey_pem := pem.EncodeToMemory(
&pem.Block
Type: "RSA PUBLIC KEY",
Bytes: pubkey_bytes,
,
)
return string(pubkey_pem), nil
func main()
// generate a 1024-bit private-key
priv, err := rsa.GenerateKey(rand.Reader, 1024)
// extract the public key from the private key as string
pub := &priv.PublicKey
message := []byte("test message")
hashed := sha256.Sum256(message)
signature, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashed[:])
if err != nil
fmt.Printf("Error from signing: %s\n", err)
return
err = rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, hashed[:], signature)
if err != nil
fmt.Printf("Error from verification: %s\n", err)
return
else
fmt.Printf("signature is verified\n")
//calling function to export private key into PEM file
pem_priv := ExportRsaPrivateKeyAsPemStr(priv)
//writing private key to file
WriteToFile(pem_priv, "private-key.pem")
//calling function to export public key as pPEM file
pem_pub, _ := ExportRsaPublicKeyAsPemStr(pub)
WriteToFile(pem_pub, "public-key.pem")
Public-key_encryption.go
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
)
//ParseRsaPublicKeyFromPemStr takes a publicKeyPEM file as a string and returns a rsa.PublicKey object
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error)
block, _ := pem.Decode([]byte(pubPEM))
if block == nil
return nil, errors.New("failed to parse PEM block containing the key")
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil
return nil, err
switch pub := pub.(type)
case *rsa.PublicKey:
return pub, nil
default:
break // fall through
return nil, errors.New("Key type is not RSA")
func main()
//reading in the public key file to be passed the the rsa object creator
PublicKeyAsString, err := ioutil.ReadFile("public-key.pem")
if err != nil
fmt.Print(err)
//Creating parsing Public PEM key to *rsa.PublicKey
rsa_public_key_object, _ := ParseRsaPublicKeyFromPemStr(string(PublicKeyAsString))
challengeMsg := []byte("c")
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsa_public_key_object, challengeMsg, nil)
if err != nil
fmt.Printf("Error from encryption: %s\n", err)
return
fmt.Printf("%x", ciphertext)
私钥解密.go
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
)
//takes a privatekey PEM file as a string and returns a pointer rsa.PublicKey object
func parseRsaPrivateKeyFromPemStr(p string) (*rsa.PrivateKey, error)
block, _ := pem.Decode([]byte(p))
if block == nil
return nil, errors.New("failed to parse PEM block containing the key")
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil
return nil, err
return key, nil
func main()
//reading in the public key file to be passed the the rsa object creator
PrivateKeyAsString, err := ioutil.ReadFile("private-key.pem")
if err != nil
fmt.Print(err)
//Creating parsing private PEM key to *rsa.PublicKey
rsa_private_key_object, _ := parseRsaPrivateKeyFromPemStr(string(PrivateKeyAsString))
ciphertext := []byte("1f58ab29106c7971c9a4307c39b6b09f8910b7ac38a8d0abc15de14cbb0f651aa5c7ca377fd64a20017eaaff0a57358bc8dd05645c8b2b24bbb137ab2e5cf657f9a6a7593ce8d043dd774d79986b00f679fc1492a6ed4961f0e1941a5ef3c6ec99f952b0756700a05314c31c768fe9463f77f23312a51a97587b04b4d8b50de0")
plaintext, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, rsa_private_key_object, ciphertext, nil)
if err != nil
fmt.Printf("Error from decryption: %s\n", err)
return
fmt.Printf("\nPlaintext: %s\n", string(plaintext))
请告诉我需要更改的内容。这是我的第一个加密项目,我开始眼袋了哈哈
【问题讨论】:
【参考方案1】:你已经接近了。在加密部分,您生成一个带有%x
格式字符串的十六进制字符串。所以,在解密部分,你应该做相应的十六进制解码。
在你的Private-key-decryption.go
,更改
ciphertext := []byte("1f58ab29106c7971c9a4307c39b6b09f8910b7ac38a8d0abc15de14cbb0f651aa5c7ca377fd64a20017eaaff0a57358bc8dd05645c8b2b24bbb137ab2e5cf657f9a6a7593ce8d043dd774d79986b00f679fc1492a6ed4961f0e1941a5ef3c6ec99f952b0756700a05314c31c768fe9463f77f23312a51a97587b04b4d8b50de0")
到
ciphertext, err := hex.DecodeString("1f58ab29106c7971c9a4307c39b6b09f8910b7ac38a8d0abc15de14cbb0f651aa5c7ca377fd64a20017eaaff0a57358bc8dd05645c8b2b24bbb137ab2e5cf657f9a6a7593ce8d043dd774d79986b00f679fc1492a6ed4961f0e1941a5ef3c6ec99f952b0756700a05314c31c768fe9463f77f23312a51a97587b04b4d8b50de0")
if err != nil
fmt.Printf("Error from hex decode: %s\n", err)
return
【讨论】:
以上是关于使用 RSA/PEM 文件解密测试消息时出错的主要内容,如果未能解决你的问题,请参考以下文章