LoginSignup
1
0

【Golang】Go で OpenPGP のペア鍵を生成する【GopenPGP】

Last updated at Posted at 2022-11-11

Go 言語(以下 Golang)で OpenPGP に準拠した公開鍵と秘密鍵を作りたい。

つまり、OpenPGP 互換の鍵ペアを Golang で作ろうと思うも、Go 公式のドキュメントを見ると Deprecated(廃止)になっていて、ガチョーン。

しかも、 golang.org/x/crypto/openpgp を使っていると、CI/ID などの脆弱性スキャナーで CVE-2022-27191 の脆弱性を指摘される。

さらに、Go の公式は「後継のパッケージは色々あるけど、私たちの方から『これがオススメ』というものはないよ」ときたもんだ。どうしよう。

TL; DR (今北産業)

2022/11/12 現在のスター数、更新頻度、利用者数から見て github.com/ProtonMail/go-crypto パッケージだが、そこから OpenPGP のみに特化スピンオフさせた GopenPGP がよさげ

  1. PGP のゴタゴタの後、規格化されたのが OpenPGP である。
    OpenPGP はアプリの実装規格(RFC4880なので、管理団体は存在しても OpenPGP というアプリは存在しない。「OpenPGP なんとか」というのは「OpenPGP(の機能に準拠した)なんとか」という意味。また、OpenPGP は、利用する暗号化アルゴリズムに RSACurve25519 などが選択できる。つまり、PGP の鍵も、アルゴリズムが RSA なら中身は実質 RSA の鍵と同じである。
  2. 有名な GPG(GnuPG, GNU Privacy Guard)は、OpenPGP を C 言語で実装したアプリである。
    つまり、GPG も OpenPGP の 1 つ(の実装)である。他言語でも実装ライブラリや、実装アプリは多数存在する。また、Golang の OpenPGP 用パッケージも複数ある
  3. GopenPGP を検討してどうか。
    Mozilla の暗号用エディタ SOPS(Go 製)で現在使っているのが Proton Mailgithub.com/ProtonMail/go-crypto パッケージ。本家 golang.org/x/crypto/openpgp をフォークして現在でもメンテナンスしている。そして、そこから OpenPGP のみをスピンオフさせて使いやすくしたのが GopenPGPgithub.com/ProtonMail/gopenpgp パッケージ。良さげだったら GitHub スターをつけよう。

この記事は、OpenPGP に準拠したアプリで RSA アルゴリズムを利用したい場合を想定しています。

TS; DR

go get "github.com/ProtonMail/gopenpgp/v2"
GolangでPGP鍵のペアを作成
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-----
}

  1. https://ja.wikipedia.org/wiki/%E3%83%8F%E3%82%A4%E3%83%96%E3%83%AA%E3%83%83%E3%83%89%E6%9A%97%E5%8F%B7

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0