【Golang】使用 Go 生成 OpenPGP 的密钥对【GopenPGP】
我想用Go语言(以下简称Golang)创建符合OpenPGP标准的公钥和私钥。
换句话说,我打算在 Golang 中创建一个兼容 OpenPGP 的密钥对,但当我查看 Go 官方文档时,发现它已被标记为废弃,真是不太好。
而且,当使用 golang.org/x/crypto/openpgp 时,会在 CI/ID 等漏洞扫描器中发现 CVE-2022-27191 的漏洞。
此外,Go的官方表示:“虽然有很多候选的包供选择,但我们没有针对性地推荐任何一个。”我该怎么办呢?
太长不看(今北産業)
根据截至2022年11月12日的星级、更新频率和用户数量来看,github.com/ProtonMail/go-crypto包似乎很不错,但从那个包中衍生出来的专注于OpenPGP的GopenPGP似乎更好。
-
- 经过PGP的混乱之后,OpenPGP被标准化。OpenPGP是一个应用程序的实施规范(RFC4880),因此虽然有管理机构但不存在名为OpenPGP的应用程序。”OpenPGP something”的意思是”符合OpenPGP功能的something”。此外,OpenPGP可以选择使用的加密算法包括RSA和Curve25519。也就是说,如果PGP的密钥算法是RSA,那么实际上其内容与RSA密钥相同。
著名的GPG(GnuPG,GNU Privacy Guard)是用C语言实现的OpenPGP应用程序。也就是说,GPG也是OpenPGP的一个(实现)。其他编程语言中也存在许多实现库和实现应用程序。此外,Golang还有多个用于OpenPGP的包。
考虑一下GopenPGP。我目前在Mozilla的加密编辑器SOPS(由Go制作)中使用的是Proton Mail的github.com/ProtonMail/go-crypto包。它是根据golang.org/x/crypto/openpgp进行分支和维护的。然后,从那里分离出OpenPGP并使其更易于使用的是GopenPGP的github.com/ProtonMail/gopenpgp包。如果看起来不错,就给它点一个GitHub的星星吧。
如果想要在符合OpenPGP标准的应用程序中使用RSA算法,可以直接选择使用Ed25519来进行签名。(也可以用于Git提交)
Go官方包:golang.org/x/crypto/ed25519
如果只想简单地对数据进行加密,建议使用AES-256对称密钥加密。
Go官方包:golang.org/x/crypto/aes
如果只想简单地使用公钥和私钥加密,建议使用Curve25519(x25519函数实现)算法而不是RSA,并交换AES-256的共享密钥。
Go官方包:golang.org/x/crypto/curve25519
GopenPGP包:github.com/ProtonMail/gopenpgp/v2
(这是Go官方的一个封装器,符合OpenPGP标准,并使用Curve25519算法)
如果只是想简单地尝试最先进的混合加密算法1,可以尝试由NIST举办的抗量子计算算法竞赛的CRYSTALS团队开发的”KYBER算法”。
尽管NIST还未正式发布,但计划将其作为OpenPGP的算法。Kyber768与+椭圆曲线密码X25519的组合被确定为必需(MUST)组合。
官方的C语言实现:Kyber | pq-crystals @ GitHub
Cloudflare开发的Go语言实现:CIRCL密码库 @ GitHub
Kyber PKE(公钥加密)的使用方法:【Golang】用Kyber算法进行公钥加密(PKE)@ Qiita
Kyber KEM(密钥交换加密)
附加信息:Dilithium数字签名(Dilithium是抗量子计算机的数字签名算法竞赛的获胜者之一,也是CRYSTALS团队开发的算法)
太长了,没时间看。
go get "github.com/ProtonMail/gopenpgp/v2"
package main
import (
"fmt"
"log"
"strings"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/gopenpgp/v2/helper"
)
func main() {
passphrase := []byte("MyVeryStrongSecretPhrase")
name := "My Name"
email := "my.name@example.com"
// Create RSA Secret Key (PEM 形式)
rsaBits := 4096
// 鍵のバリエーション:
//
// RSA, string
// rsaKey, err := helper.GenerateKey(name, email, passphrase, "rsa", rsaBits)
//
// Curve25519, string
// ecKey, err := helper.GenerateKey(name, email, passphrase, "x25519", 0)
//
// RSA, Key struct
// rsaKey, err := crypto.GenerateKey(name, email, "rsa", rsaBits)
//
// Curve25519, Key struct
// ecKey, err := crypto.GenerateKey(name, email, "x25519", 0)
//
// 以下は RSA-4096 の鍵ペア作成
rsaKey, err := helper.GenerateKey(name, email, passphrase, "rsa", rsaBits)
if err != nil {
log.Fatal(err)
}
fmt.Printf("RSA4096 Secret:\n%v\n\n", rsaKey)
// Generate RSA Public Key (PEM 形式)
keyRing, err := crypto.NewKeyFromArmoredReader(strings.NewReader(rsaKey))
if err != nil {
log.Fatal(err)
}
publicKey, err := keyRing.GetArmoredPublicKey()
if err != nil {
log.Fatal(err)
}
fmt.Printf("RSA4096 Public:\n%v\n", publicKey)
// Output:
// RSA4096 Secret:
// -----BEGIN PGP PRIVATE KEY BLOCK-----
// Version: GopenPGP 2.4.10
// Comment: https://gopenpgp.org
//
// xcaGBGNuTusBEAC16zBOWYqd6uEK7aUIHz3VKGXc9X/94yXaIq4xdVJd/MZp/379
// 8lfWxkwuN/+KT2TXMQerq7s765ZI1t25p+YPtzXg+fr4JdVlx6EvhGatuCstBTys
// ** snip **
// Bd4MBg+SCbI9+X04nDtIOnFQjv7Vw3l9PGe1HXhCOZlIZXZ3x2kKCjLBZn+/qi9b
// lMHXXA3VMuZ5IeHdL5EZJXPbhFhU/7Ijw1h2pqoUq/zQoRMLXQ==
// =bgBm
// -----END PGP PRIVATE KEY BLOCK-----
//
// RSA4096 Public:
// -----BEGIN PGP PUBLIC KEY BLOCK-----
// Version: GopenPGP 2.4.10
// Comment: https://gopenpgp.org
//
// xsFNBGNuTusBEAC16zBOWYqd6uEK7aUIHz3VKGXc9X/94yXaIq4xdVJd/MZp/379
// 8lfWxkwuN/+KT2TXMQerq7s765ZI1t25p+YPtzXg+fr4JdVlx6EvhGatuCstBTys
// ** snip **
// dKRdba+jzP/OIn8YJsEF3gwGD5IJsj35fTicO0g6cVCO/tXDeX08Z7UdeEI5mUhl
// dnfHaQoKMsFmf7+qL1uUwddcDdUy5nkh4d0vkRklc9uEWFT/siPDWHamqhSr/NCh
// Ewtd
// =mwx1
// -----END PGP PUBLIC KEY BLOCK-----
}