Skip to content

Instantly share code, notes, and snippets.

@nl5887
Last active April 27, 2016 18:15
Show Gist options
  • Save nl5887/30893d2186a27e1b49a3 to your computer and use it in GitHub Desktop.
Save nl5887/30893d2186a27e1b49a3 to your computer and use it in GitHub Desktop.
Generate OpenPGP signature using Golang
package main
import (
"bytes"
"crypto/rsa"
"fmt"
"log"
"strings"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)
func main() {
var config packet.Config
currentTime := config.Now()
bits := 2048
uid := packet.NewUserId("name", "comment", "email")
if uid == nil {
return
}
signingPriv, err := rsa.GenerateKey(config.Random(), bits)
if err != nil {
return
}
encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
if err != nil {
return
}
e := &openpgp.Entity{
PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
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: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
Sig: &packet.Signature{
CreationTime: currentTime,
SigType: packet.SigTypeSubkeyBinding,
PubKeyAlgo: packet.PubKeyAlgoRSA,
Hash: config.Hash(),
FlagsValid: true,
FlagEncryptStorage: true,
FlagEncryptCommunications: true,
IssuerKeyId: &e.PrimaryKey.KeyId,
KeyLifetimeSecs: &secs,
},
}
e.Subkeys[0].PublicKey.IsSubkey = true
e.Subkeys[0].PrivateKey.IsSubkey = true
signingKey := packet.NewRSAPrivateKey(currentTime, signingPriv)
priv := packet.NewRSAPrivateKey(currentTime, encryptingPriv)
// Sign identities
for _, id := range e.Identities {
err := id.SelfSignature.SignUserId(uid.Id, e.PrimaryKey, signingKey, nil)
if err != nil {
fmt.Println(err)
return
}
}
// Sign subkeys
for _, subkey := range e.Subkeys {
err := subkey.Sig.SignKey(subkey.PublicKey, signingKey, nil)
if err != nil {
log.Fatal(err)
}
}
buffer := &bytes.Buffer{}
w, err := armor.Encode(buffer, openpgp.PublicKeyType, map[string]string{})
e.Serialize(w)
w.Close()
fmt.Println(buffer.String())
r, err := armor.Decode(strings.NewReader(buffer.String()))
fromReader := packet.NewReader(r.Body)
_, err = openpgp.ReadEntity(fromReader)
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment