OpenPGP – 尝试加密失败

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

OpenPGP - attempted encryption fails

问题

我正在尝试获取一个仓库(https://github.com/jchavannes/go-pgp)进行加密。
运行代码时出现以下错误:

EOF @ File: main.go  Function: main.main Line: 21
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x52cdc2]

整合后的代码如下:

package main

import (
	"bytes"
	"compress/gzip"
	"crypto"
	"errors"
	"fmt"
	"io"

	"github.com/jimlawless/whereami"
	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
	"golang.org/x/crypto/openpgp/packet"
)

func main() {
	// Create public key entity
	publicKeyPacket, err := getPublicKeyPacket([]byte(TestPublicKey))
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
	pubEntity, err := createEntityFromKeys(publicKeyPacket, nil)
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}

	// Encrypt message
	encrypted, _ := encrypt(pubEntity, []byte(TestMessage))
	fmt.Println(encrypted)
}

func getPublicKeyPacket(publicKey []byte) (*packet.PublicKey, error) {
	publicKeyReader := bytes.NewReader(publicKey)
	block, err := armor.Decode(publicKeyReader)
	if err != nil {
		return nil, err
	}

	if block.Type != openpgp.PublicKeyType {
		return nil, errors.New("Invalid public key data")
	}

	packetReader := packet.NewReader(block.Body)
	pkt, err := packetReader.Next()
	if err != nil {
		return nil, err
	}

	key, ok := pkt.(*packet.PublicKey)
	if !ok {
		return nil, err
	}
	return key, nil
}

func createEntityFromKeys(pubKey *packet.PublicKey, privKey *packet.PrivateKey) (*openpgp.Entity, error) {
	config := packet.Config{
		DefaultHash:            crypto.SHA256,
		DefaultCipher:          packet.CipherAES256,
		DefaultCompressionAlgo: packet.CompressionZLIB,
		CompressionConfig: &packet.CompressionConfig{
			Level: 9,
		},
		RSABits: 4096,
	}
	currentTime := config.Now()
	uid := packet.NewUserId("", "", "")

	e := openpgp.Entity{
		PrimaryKey: pubKey,
		PrivateKey: privKey,
		Identities: make(map[string]*openpgp.Identity),
	}
	isPrimaryId := false

	e.Identities[uid.Id] = &openpgp.Identity{
		Name:   uid.Name,
		UserId: uid,
		SelfSignature: &packet.Signature{
			CreationTime: currentTime,
			SigType:      packet.SigTypePositiveCert,
			PubKeyAlgo:   packet.PubKeyAlgoRSA,
			Hash:         config.Hash(),
			IsPrimaryId:  &isPrimaryId,
			FlagsValid:   true,
			FlagSign:     true,
			FlagCertify:  true,
			IssuerKeyId:  &e.PrimaryKey.KeyId,
		},
	}

	keyLifetimeSecs := uint32(86400 * 365)

	e.Subkeys = make([]openpgp.Subkey, 1)
	e.Subkeys[0] = openpgp.Subkey{
		PublicKey:  pubKey,
		PrivateKey: privKey,
		Sig: &packet.Signature{
			CreationTime:              currentTime,
			SigType:                   packet.SigTypeSubkeyBinding,
			PubKeyAlgo:                packet.PubKeyAlgoRSA,
			Hash:                      config.Hash(),
			PreferredHash:             []uint8{8}, // SHA-256
			FlagsValid:                true,
			FlagEncryptStorage:        true,
			FlagEncryptCommunications: true,
			IssuerKeyId:               &e.PrimaryKey.KeyId,
			KeyLifetimeSecs:           &keyLifetimeSecs,
		},
	}
	return &e, nil
}

func encrypt(entity *openpgp.Entity, message []byte) ([]byte, error) {
	// Create buffer to write output to
	buf := new(bytes.Buffer)

	// Create encoder
	encoderWriter, err := armor.Encode(buf, "Message", make(map[string]string))
	if err != nil {
		return []byte{}, fmt.Errorf("Error creating OpenPGP armor: %v", err)
	}

	// Create encryptor with encoder
	encryptorWriter, err := openpgp.Encrypt(encoderWriter, []*openpgp.Entity{entity}, nil, nil, nil)
	if err != nil {
		return []byte{}, fmt.Errorf("Error creating entity for encryption: %v", err)
	}

	// Create compressor with encryptor
	compressorWriter, err := gzip.NewWriterLevel(encryptorWriter, gzip.BestCompression)
	if err != nil {
		return []byte{}, fmt.Errorf("Invalid compression level: %v", err)
	}

	// Write message to compressor
	messageReader := bytes.NewReader(message)
	_, err = io.Copy(compressorWriter, messageReader)
	if err != nil {
		return []byte{}, fmt.Errorf("Error writing data to compressor: %v", err)
	}

	compressorWriter.Close()
	encryptorWriter.Close()
	encoderWriter.Close()

	// Return buffer output - an encoded, encrypted, and compressed message
	return buf.Bytes(), nil
}

const TestMessage = "hello world"

const TestPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=5NT7
-----END PGP PRIVATE KEY BLOCK-----`

const TestPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf
oPCOq67XDseK71ZSevrIt7EdTLAzl0xN8kB+8iedAGM5OCakDe3R8L83OGy1Em26
PbrrYs3TYKGDXW65TsGYCoETROGgU2zPvuBDU1RvVvd9vAlWHQis43BOWaaakCEc
00V3sdNcfV+lz7fNUXEgtmTCCr9NWX4gO3YeenIIxep4WD27VwscW5Q2B1cnxcFL
+TZzE2oVjtXljGSO94XsekuNU47zwJZNGyU6SSlSZ+KVXuSdkRRfNYHlgDWg5b8C
xVmdVUfsx3bmNlOlXoyETj83xvRlLxn3PYIgOz6OlYGba5oDogK2QLXGTXK1o9OE
kgoghmCNQqxocvb1hQXT8cEynIbAdc6/JknYaoic6ka1iTTz3uN8FEPw5gRlidcQ
3wkbmqIS0LJs3JmVbD7/BxMY1dwqMyvulfnLiTsWSPvk41o7dHf077t23V9w78Jg
h4Xq4HRvt37PtuO6eWW3c5aUIWmvvDqMbMEqp2y23noYoVNqEpVoHolDdoCSurv/
XxbNBnj46XwaIs6OlrO2htV0al2/WVTNnSLxCyoHXoJEDXyaOyNKn1jM/FczgYQJ
069uC804ohOfjLmbtUEYE7Hjeo5utPm2ryjnakgV5AStKgL0SyFZUwN/DwARAQAB
=gO1a
-----END PGP PUBLIC KEY BLOCK-----`

有任何修复这个问题的想法吗?

英文:

I am attempting to get a repo (https://github.com/jchavannes/go-pgp) to encrypt.
When running the code I get

EOF @ File: main.go  Function: main.main Line: 21
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x52cdc2]

The consolidated code looks like:

package main
import (
"bytes"
"compress/gzip"
"crypto"
"errors"
"fmt"
"io"
"github.com/jimlawless/whereami"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)
func main() {
// Create public key entity
publicKeyPacket, err := getPublicKeyPacket([]byte(TestPublicKey))
if err != nil {
fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
}
pubEntity, err := createEntityFromKeys(publicKeyPacket, nil)
if err != nil {
fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
}
// Encrypt message
encrypted, _ := encrypt(pubEntity, []byte(TestMessage))
fmt.Println(encrypted)
}
func getPublicKeyPacket(publicKey []byte) (*packet.PublicKey, error) {
publicKeyReader := bytes.NewReader(publicKey)
block, err := armor.Decode(publicKeyReader)
if err != nil {
return nil, err
}
if block.Type != openpgp.PublicKeyType {
return nil, errors.New("Invalid public key data")
}
packetReader := packet.NewReader(block.Body)
pkt, err := packetReader.Next()
if err != nil {
return nil, err
}
key, ok := pkt.(*packet.PublicKey)
if !ok {
return nil, err
}
return key, nil
}
func createEntityFromKeys(pubKey *packet.PublicKey, privKey *packet.PrivateKey) (*openpgp.Entity, error) {
config := packet.Config{
DefaultHash:            crypto.SHA256,
DefaultCipher:          packet.CipherAES256,
DefaultCompressionAlgo: packet.CompressionZLIB,
CompressionConfig: &packet.CompressionConfig{
Level: 9,
},
RSABits: 4096,
}
currentTime := config.Now()
uid := packet.NewUserId("", "", "")
e := openpgp.Entity{
PrimaryKey: pubKey,
PrivateKey: privKey,
Identities: make(map[string]*openpgp.Identity),
}
isPrimaryId := false
e.Identities[uid.Id] = &openpgp.Identity{
Name:   uid.Name,
UserId: uid,
SelfSignature: &packet.Signature{
CreationTime: currentTime,
SigType:      packet.SigTypePositiveCert,
PubKeyAlgo:   packet.PubKeyAlgoRSA,
Hash:         config.Hash(),
IsPrimaryId:  &isPrimaryId,
FlagsValid:   true,
FlagSign:     true,
FlagCertify:  true,
IssuerKeyId:  &e.PrimaryKey.KeyId,
},
}
keyLifetimeSecs := uint32(86400 * 365)
e.Subkeys = make([]openpgp.Subkey, 1)
e.Subkeys[0] = openpgp.Subkey{
PublicKey:  pubKey,
PrivateKey: privKey,
Sig: &packet.Signature{
CreationTime:              currentTime,
SigType:                   packet.SigTypeSubkeyBinding,
PubKeyAlgo:                packet.PubKeyAlgoRSA,
Hash:                      config.Hash(),
PreferredHash:             []uint8{8}, // SHA-256
FlagsValid:                true,
FlagEncryptStorage:        true,
FlagEncryptCommunications: true,
IssuerKeyId:               &e.PrimaryKey.KeyId,
KeyLifetimeSecs:           &keyLifetimeSecs,
},
}
return &e, nil
}
func encrypt(entity *openpgp.Entity, message []byte) ([]byte, error) {
// Create buffer to write output to
buf := new(bytes.Buffer)
// Create encoder
encoderWriter, err := armor.Encode(buf, "Message", make(map[string]string))
if err != nil {
return []byte{}, fmt.Errorf("Error creating OpenPGP armor: %v", err)
}
// Create encryptor with encoder
encryptorWriter, err := openpgp.Encrypt(encoderWriter, []*openpgp.Entity{entity}, nil, nil, nil)
if err != nil {
return []byte{}, fmt.Errorf("Error creating entity for encryption: %v", err)
}
// Create compressor with encryptor
compressorWriter, err := gzip.NewWriterLevel(encryptorWriter, gzip.BestCompression)
if err != nil {
return []byte{}, fmt.Errorf("Invalid compression level: %v", err)
}
// Write message to compressor
messageReader := bytes.NewReader(message)
_, err = io.Copy(compressorWriter, messageReader)
if err != nil {
return []byte{}, fmt.Errorf("Error writing data to compressor: %v", err)
}
compressorWriter.Close()
encryptorWriter.Close()
encoderWriter.Close()
// Return buffer output - an encoded, encrypted, and compressed message
return buf.Bytes(), nil
}
const TestMessage = "hello world"
const TestPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=5NT7
-----END PGP PRIVATE KEY BLOCK-----`
const TestPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf
oPCOq67XDseK71ZSevrIt7EdTLAzl0xN8kB+8iedAGM5OCakDe3R8L83OGy1Em26
PbrrYs3TYKGDXW65TsGYCoETROGgU2zPvuBDU1RvVvd9vAlWHQis43BOWaaakCEc
00V3sdNcfV+lz7fNUXEgtmTCCr9NWX4gO3YeenIIxep4WD27VwscW5Q2B1cnxcFL
+TZzE2oVjtXljGSO94XsekuNU47zwJZNGyU6SSlSZ+KVXuSdkRRfNYHlgDWg5b8C
xVmdVUfsx3bmNlOlXoyETj83xvRlLxn3PYIgOz6OlYGba5oDogK2QLXGTXK1o9OE
kgoghmCNQqxocvb1hQXT8cEynIbAdc6/JknYaoic6ka1iTTz3uN8FEPw5gRlidcQ
3wkbmqIS0LJs3JmVbD7/BxMY1dwqMyvulfnLiTsWSPvk41o7dHf077t23V9w78Jg
h4Xq4HRvt37PtuO6eWW3c5aUIWmvvDqMbMEqp2y23noYoVNqEpVoHolDdoCSurv/
XxbNBnj46XwaIs6OlrO2htV0al2/WVTNnSLxCyoHXoJEDXyaOyNKn1jM/FczgYQJ
069uC804ohOfjLmbtUEYE7Hjeo5utPm2ryjnakgV5AStKgL0SyFZUwN/DwARAQAB
=gO1a
-----END PGP PUBLIC KEY BLOCK-----`

Any ideas how to fix this?

答案1

得分: 1

tl;dr

  1. 始终检查错误。
  2. x/crypto/openpgp 包已被弃用,你不应该使用它。

这是你的错误信息:

EOF @ File: main.go  Function: main.main Line: 21

这是来自 getPublicKeyPacket([]byte(TestPublicKey)) 的错误,我们可以看到:

    publicKeyReader := bytes.NewReader(publicKey)
    block, err := armor.Decode(publicKeyReader)
    if err != nil {
        return nil, err
    }

查看 armor.Decode 的文档,我们可以看到(重点在于):

> Decode 从给定的 Reader 中读取一个 PGP armored 块。它会忽略前导垃圾。如果找不到块,它会返回 nil, io.EOF。

所以,看起来你有一个无效的公钥块。让我们测试一下这个理论!

如果我们将 TestPublicKey 的数据写入一个文件...

-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf
oPCOq67XDseK71ZSevrIt7EdTLAzl0xN8kB+8iedAGM5OCakDe3R8L83OGy1Em26
PbrrYs3TYKGDXW65TsGYCoETROGgU2zPvuBDU1RvVvd9vAlWHQis43BOWaaakCEc
00V3sdNcfV+lz7fNUXEgtmTCCr9NWX4gO3YeenIIxep4WD27VwscW5Q2B1cnxcFL
+TZzE2oVjtXljGSO94XsekuNU47zwJZNGyU6SSlSZ+KVXuSdkRRfNYHlgDWg5b8C
xVmdVUfsx3bmNlOlXoyETj83xvRlLxn3PYIgOz6OlYGba5oDogK2QLXGTXK1o9OE
kgoghmCNQqxocvb1hQXT8cEynIbAdc6/JknYaoic6ka1iTTz3uN8FEPw5gRlidcQ
3wkbmqIS0LJs3JmVbD7/BxMY1dwqMyvulfnLiTsWSPvk41o7dHf077t23V9w78Jg
h4Xq4HRvt37PtuO6eWW3c5aUIWmvvDqMbMEqp2y23noYoVNqEpVoHolDdoCSurv/
XxbNBnj46XwaIs6OlrO2htV0al2/WVTNnSLxCyoHXoJEDXyaOyNKn1jM/FczgYQJ
069uC804ohOfjLmbtUEYE7Hjeo5utPm2ryjnakgV5AStKgL0SyFZUwN/DwARAQAB
=gO1a
-----END PGP PUBLIC KEY BLOCK-----

...然后尝试使用 gpg 导入它,我们可以看到:

$ gpg --import testpublickey.asc
gpg: invalid armor header: xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf\n
gpg: key 39078898F94F4667: new key but contains no user ID - skipped

看起来 gpg 也是这样认为的。让我们生成一个正确的公钥,看看问题是否解决:

$ gpg --full-generate-key
[...]
pub   rsa3072 2022-06-04 [SC]
      92F9D24D5428E3D2B5FE5774A7F5A28D78317D17
uid                      Test Key <test@example.com>
sub   rsa3072 2022-06-04 [E]
$ gpg --export -a test@example.com > testpublickey.asc
$ gpg --export-secret-key -a test@example.com > testsecretkey.asc

如果我们将 testpublickey.asc 的内容嵌入到你的代码中并编译,现在它将不再出现错误...

$ go build
$ ./gpgtest
[]

...尽管它似乎没有生成有用的输出。但这是因为你忽略了 encrypt 的错误。如果我们处理错误响应:

	encrypted, err := encrypt(pubEntity, []byte(TestMessage))
	if err != nil {
		panic(err)
	}
	fmt.Println(encrypted)

然后我们会看到:

panic: Error creating entity for encryption: openpgp: invalid argument: cannot encrypt because no candidate hash functions are compiled in. (Wanted RIPEMD160 in this case.)

goroutine 1 [running]:
main.main()
        /home/lars/tmp/go/main.go:31 +0xe9

这个错误似乎在这里得到了解决,它告诉我们解决方案是通过添加以下代码导入适当的哈希函数:

import (
    ...
    _ "golang.org/x/crypto/ripemd160"
)

进行这个更改并重新编译后,我们现在可以看到输出:

	fmt.Println(string(encrypted))

这给出了:

-----BEGIN Message-----

wcDMA6f1oo14MX0XAQwABlLztwGC16in9i0kHm4M7FETC+1xgJDllBEGKqZWvPIb
FruPomy+jBPMROuVpZl9qxBTJwkTvhXxMZsSZz+mWOzrsAanhffZtCRbZ5BC+f8U
1iAkt35Sk73tN7w62+G7Unza0KlE8l3eqEb947wZSYAufdVnDESRd6ScTFuj/pxp
0pnfpaOAjjZPp9DOpExpU+yIij94t0UrAwndsSE3D3Bi1DfJ1Q9GPgYQbplwio3u
wfzFZOonIH2TG0AUwiY9lLVTu+u9rj5PovGdXuaIGTw26IAn05Xo3DRPdgee+W+2
qMHEDE6PoZFcL3eTJ8ed0IbvRAHZ3oovJpo/nJ2Pf7RfJcsujYYfsAv7Y2jmFWDd
cwo4NStRBCEZBhTfkZTJUI4kSpOtiXK2kqyQYuzKhQB3UnoMi4vbge9aOoT6x27f
u/UuvdRAuZ4CjD0ptyauFZKPwQxkYZ3R3LeUrPXbOQ1KPLWtnECseeqSqGVWpmVs
1DgjgF+cVXovuUFcWHhl0uYB/Q0NJCQV59t7QMtHalBIOv/KSOQUlOjGpRaZB5GL
NXRSSTLYZOUXqUpFMC8em+uoT3KFLxeYVG/5wB5YXyK/47CZvEvK32g54rS5dlHh
JergyAA=
=iYGx
-----END Message-----

但是,同样的答案也告诉我们 crypto/openpgp 包已被弃用,你不应该使用它。链接的问题中提供了一些替代方案的建议。

英文:

tl;dr

  1. always check for errors.
  2. The x/crypto/openpgp package is deprecated and you shouldn't be using it.

So here's your error:

EOF @ File: main.go  Function: main.main Line: 21

That's coming back from getPublicKeyPacket([]byte(TestPublicKey)), where we see:

    publicKeyReader := bytes.NewReader(publicKey)
block, err := armor.Decode(publicKeyReader)
if err != nil {
return nil, err
}

Looking at the documentation for armor.Decode, we see (emphasis mine):

> Decode reads a PGP armored block from the given Reader. It will ignore leading garbage. If it doesn't find a block, it will return nil, io.EOF.

So, it looks like you have an invalid public key block. Let's test that theory!

If we take the data from TestPublicKey and write it to a file...

-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf
oPCOq67XDseK71ZSevrIt7EdTLAzl0xN8kB+8iedAGM5OCakDe3R8L83OGy1Em26
PbrrYs3TYKGDXW65TsGYCoETROGgU2zPvuBDU1RvVvd9vAlWHQis43BOWaaakCEc
00V3sdNcfV+lz7fNUXEgtmTCCr9NWX4gO3YeenIIxep4WD27VwscW5Q2B1cnxcFL
+TZzE2oVjtXljGSO94XsekuNU47zwJZNGyU6SSlSZ+KVXuSdkRRfNYHlgDWg5b8C
xVmdVUfsx3bmNlOlXoyETj83xvRlLxn3PYIgOz6OlYGba5oDogK2QLXGTXK1o9OE
kgoghmCNQqxocvb1hQXT8cEynIbAdc6/JknYaoic6ka1iTTz3uN8FEPw5gRlidcQ
3wkbmqIS0LJs3JmVbD7/BxMY1dwqMyvulfnLiTsWSPvk41o7dHf077t23V9w78Jg
h4Xq4HRvt37PtuO6eWW3c5aUIWmvvDqMbMEqp2y23noYoVNqEpVoHolDdoCSurv/
XxbNBnj46XwaIs6OlrO2htV0al2/WVTNnSLxCyoHXoJEDXyaOyNKn1jM/FczgYQJ
069uC804ohOfjLmbtUEYE7Hjeo5utPm2ryjnakgV5AStKgL0SyFZUwN/DwARAQAB
=gO1a
-----END PGP PUBLIC KEY BLOCK-----

...and then try to import that with gpg, we see:

$ gpg --import testpublickey.asc
gpg: invalid armor header: xsFNBFkNK+ABEADUpjJ/kz3j+iz9qnzUb6ONw+WHSLp8umnd1z06SBVkWFjYReqf\n
gpg: key 39078898F94F4667: new key but contains no user ID - skipped

It looks as if gpg agrees. Let's generate a proper public key and see if the problem goes away:

$ gpg --full-generate-key
[...]
pub   rsa3072 2022-06-04 [SC]
92F9D24D5428E3D2B5FE5774A7F5A28D78317D17
uid                      Test Key <test@example.com>
sub   rsa3072 2022-06-04 [E]
$ gpg --export -a test@example.com > testpublickey.asc
$ gpg --export-secret-key -a test@example.com > testsecretkey.asc

If we embed the content of testpublickey.asc into your code and compile, it now runs without errors...

$ go build
$ ./gpgtest
[]

...although it doesn't appear to be generating useful output. But that's because you're ignoring the error from encrypt. If we handle an error response:

	encrypted, err := encrypt(pubEntity, []byte(TestMessage))
if err != nil {
panic(err)
}
fmt.Println(encrypted)

Then we see:

panic: Error creating entity for encryption: openpgp: invalid argument: cannot encrypt because no candidate hash functions are compiled in. (Wanted RIPEMD160 in this case.)
goroutine 1 [running]:
main.main()
/home/lars/tmp/go/main.go:31 +0xe9

And that error seems to be addressed here, which tells us the solution is to import the appropriate hash by adding:

import (
...
_ "golang.org/x/crypto/ripemd160"
)

With this change and a recompile, we now see as output:

[45 45 45 45 45 66 69 71 73 78 32 77 101 115 115 97 103 101 45 45 45 45 45 10 10 119 99 68 77 65 54 102 49 111 111 49 52 77 88 48 88 65 81 119 65 87 70 43 115 72 119 89 121 117 106 83 70 76 57 100 73 101 113 115 107 81 103 117 106 99 118 97 69 57 52 47 57 51 105 57 118 118 98 67 82 111 113 57 98 10 99 54 66 85 108 103 116 50 111 72 97 122 86 110 105 50 49 121 68 122 112 119 82 115 81 109 105 48 43 100 90 103 81 99 52 54 112 65 89 77 106 116 48 81 117 66 116 50 65 77 100 86 71 118 56 79 121 66 47 70 115 87 89 116 10 49 100 83 80 90 115 121 73 116 113 118 50 65 114 122 102 100 114 68 84 54 75 116 99 110 76 70 85 114 72 67 55 102 66 112 74 115 88 51 86 75 53 111 106 75 82 117 115 54 70 72 56 52 83 101 54 55 98 66 70 113 81 90 107 10 113 80 66 68 57 108 49 66 84 88 80 83 57 73 100 56 111 74 114 115 119 82 87 88 119 117 90 80 75 121 49 101 107 71 53 53 69 73 73 71 78 49 84 69 70 90 100 103 54 110 72 83 119 83 100 53 84 112 120 107 71 68 80 48 10 104 67 110 122 121 109 111 97 53 55 78 84 71 97 82 110 65 47 119 88 71 86 104 104 110 87 68 55 85 120 107 116 53 90 100 52 84 88 43 107 109 119 102 48 50 108 80 115 66 122 114 122 118 50 87 50 56 51 97 85 79 109 70 118 10 71 113 55 71 69 80 119 83 116 74 100 47 49 90 81 113 110 109 48 65 80 86 72 69 69 108 114 98 120 67 122 83 66 82 80 103 51 78 73 79 112 106 100 121 83 48 112 116 57 82 107 114 111 82 87 43 57 99 50 76 98 100 54 83 10 112 119 88 110 76 56 78 100 114 49 70 43 105 122 101 84 109 112 76 99 82 101 119 89 88 57 107 113 113 69 106 78 117 103 90 54 65 117 85 83 77 73 121 104 102 101 99 121 108 69 78 99 47 103 87 98 103 103 51 54 65 81 101 116 10 86 52 65 48 122 88 122 82 121 102 122 121 76 53 56 67 101 54 112 65 71 85 54 118 115 66 114 73 83 122 86 107 108 105 118 108 69 115 114 99 83 75 119 98 67 79 111 78 112 112 118 117 105 53 108 89 77 57 77 65 110 110 111 79 10 98 56 109 78 50 72 110 110 117 85 102 48 43 43 76 67 90 48 98 105 48 117 89 66 102 43 120 68 87 70 108 122 115 87 69 73 81 66 111 114 78 70 82 100 117 97 85 77 76 73 104 47 89 108 116 65 104 108 90 81 111 47 122 120 10 90 86 55 98 102 108 53 103 88 74 117 89 83 83 86 43 113 100 72 75 43 106 109 103 83 121 89 90 75 100 89 110 80 78 112 49 53 71 48 55 50 74 85 73 52 52 82 119 56 66 113 97 81 80 75 54 52 105 101 76 67 65 106 104 10 43 43 110 103 80 103 65 61 10 61 121 72 81 117 10 45 45 45 45 45 69 78 68 32 77 101 115 115 97 103 101 45 45 45 45 45]

Printing out a byte buffer isn't all that helpful, so let's wrap that with string:

	fmt.Println(string(encrypted))

And that gives us:

-----BEGIN Message-----
wcDMA6f1oo14MX0XAQwABlLztwGC16in9i0kHm4M7FETC+1xgJDllBEGKqZWvPIb
FruPomy+jBPMROuVpZl9qxBTJwkTvhXxMZsSZz+mWOzrsAanhffZtCRbZ5BC+f8U
1iAkt35Sk73tN7w62+G7Unza0KlE8l3eqEb947wZSYAufdVnDESRd6ScTFuj/pxp
0pnfpaOAjjZPp9DOpExpU+yIij94t0UrAwndsSE3D3Bi1DfJ1Q9GPgYQbplwio3u
wfzFZOonIH2TG0AUwiY9lLVTu+u9rj5PovGdXuaIGTw26IAn05Xo3DRPdgee+W+2
qMHEDE6PoZFcL3eTJ8ed0IbvRAHZ3oovJpo/nJ2Pf7RfJcsujYYfsAv7Y2jmFWDd
cwo4NStRBCEZBhTfkZTJUI4kSpOtiXK2kqyQYuzKhQB3UnoMi4vbge9aOoT6x27f
u/UuvdRAuZ4CjD0ptyauFZKPwQxkYZ3R3LeUrPXbOQ1KPLWtnECseeqSqGVWpmVs
1DgjgF+cVXovuUFcWHhl0uYB/Q0NJCQV59t7QMtHalBIOv/KSOQUlOjGpRaZB5GL
NXRSSTLYZOUXqUpFMC8em+uoT3KFLxeYVG/5wB5YXyK/47CZvEvK32g54rS5dlHh
JergyAA=
=iYGx
-----END Message-----

But that same answer also tells us that the crypto/openpgp package is deprecated and you shouldn't be using it. The linked issue has some suggestions for alternatives.

huangapple
  • 本文由 发表于 2022年6月4日 07:48:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/72496122.html
匿名

发表评论

匿名网友

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

确定