Go – Golang openpg – 创建密钥对和创建签名

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

Go - Golang openpg - Create Key pair and create signature

问题

我目前正在使用golang开发openpgp。我使用以下代码生成新的密钥对,并在生成的公钥上创建自签名:

package main

import (
    "bytes"
    "crypto"
    "time"
    "golang.org/x/crypto/openpgp"
    "golang.org/x/crypto/openpgp/armor"
    "golang.org/x/crypto/openpgp/packet"
    "fmt"
)

// 将openpgp.Entity转换为ASCII Armor
func PubEntToAsciiArmor(pubEnt *openpgp.Entity) (asciiEntity string) {
    gotWriter := bytes.NewBuffer(nil)
    wr, errEncode := armor.Encode(gotWriter, openpgp.PublicKeyType, nil)
    if errEncode != nil {
        fmt.Println("Encoding Armor ", errEncode.Error())
        return
    }
    errSerial := pubEnt.Serialize(wr)
    if errSerial != nil {
        fmt.Println("Serializing PubKey ", errSerial.Error())
    }
    errClosing := wr.Close()
    if errClosing != nil {
        fmt.Println("Closing writer ", errClosing.Error())
    }
    asciiEntity = gotWriter.String()
    return
}

func main() {
    var entity *openpgp.Entity
    entity, err := openpgp.NewEntity("itis", "test", "itis@itis3.com", nil)
    if err != nil {
        fmt.Println("ERROR")
    }

    usrIdstring := ""
    for _, uIds := range entity.Identities {
        usrIdstring = uIds.Name
    }

    var priKey = entity.PrivateKey
    var sig = new(packet.Signature)
    // 准备使用我们的配置进行签名/////这是必须的吗?
    sig.Hash = crypto.SHA1
    sig.PubKeyAlgo = priKey.PubKeyAlgo
    sig.CreationTime = time.Now()
    dur := new(uint32)
    *dur = uint32(365 * 24 * 60 * 60)
    sig.SigLifetimeSecs = dur // 一年
    issuerUint := new(uint64)
    *issuerUint = priKey.KeyId
    sig.IssuerKeyId = issuerUint
    sig.SigType = packet.SigTypeGenericCert

    err = sig.SignKey(entity.PrimaryKey, entity.PrivateKey, nil)
    if err != nil {
        fmt.Println("ERROR")
    }
    err = sig.SignUserId(usrIdstring, entity.PrimaryKey, entity.PrivateKey, nil)
    if err != nil {
        fmt.Println("ERROR")
    }

    entity.SignIdentity(usrIdstring, entity, nil)

    var copy = entity
    var asciiSignedKey = PubEntToAsciiArmor(copy)
    fmt.Println(asciiSignedKey)
}

1.) 当我序列化公钥(以获取其ASCII Armor版本)时,我收到以下错误消息:

Serializing PubKey openpgp: invalid argument: Signature: need to call Sign, SignUserId or SignKey before Serialize

我认为我已经使用了所有可能的方式在该密钥上创建签名,为什么会出现这个错误?

2.) 当我将密钥上传到密钥服务器时,我仍然收到问题1的输出,只有密钥ID和创建日期被列出,其他附加信息如自签名、用户ID字符串等都丢失了(例如:https://pgp.mit.edu/pks/lookup?search=0xbe6ee21e94a73ba5&op=index)。出了什么问题?这与错误1有关吗?

PS:我是刚开始学习golang,今天刚开始。

英文:

I'm currently working on openpgp in combination with golang. I use the following code to generate a new keypair and create a self-signature on the resulting public key:

package main
import (
"bytes"
"crypto"
"time"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
"fmt"
)
//Create ASscii Armor from openpgp.Entity
func PubEntToAsciiArmor(pubEnt *openpgp.Entity) (asciiEntity string) {
gotWriter := bytes.NewBuffer(nil)
wr, errEncode := armor.Encode(gotWriter, openpgp.PublicKeyType, nil)
if errEncode != nil {
fmt.Println("Encoding Armor ", errEncode.Error())
return
}
errSerial := pubEnt.Serialize(wr)
if errSerial != nil {
fmt.Println("Serializing PubKey ", errSerial.Error())
}
errClosing := wr.Close()
if errClosing != nil {
fmt.Println("Closing writer ", errClosing.Error())
}
asciiEntity = gotWriter.String()
return
}
func main() {
var entity *openpgp.Entity
entity, err := openpgp.NewEntity("itis", "test", "itis@itis3.com", nil)
if err != nil {
fmt.Println("ERROR")
}
usrIdstring := ""
for _, uIds := range entity.Identities {
usrIdstring = uIds.Name
}
var priKey = entity.PrivateKey
var sig = new(packet.Signature)    
//Prepare sign with our configs/////IS IT A MUST ??
sig.Hash = crypto.SHA1
sig.PubKeyAlgo = priKey.PubKeyAlgo
sig.CreationTime = time.Now()
dur := new(uint32)
*dur = uint32(365 * 24 * 60 * 60)
sig.SigLifetimeSecs = dur //a year
issuerUint := new(uint64)
*issuerUint = priKey.KeyId
sig.IssuerKeyId = issuerUint
sig.SigType = packet.SigTypeGenericCert
err = sig.SignKey(entity.PrimaryKey, entity.PrivateKey, nil)
if err != nil {
fmt.Println("ERROR")
}
err = sig.SignUserId(usrIdstring, entity.PrimaryKey, entity.PrivateKey, nil)
if err != nil {
fmt.Println("ERROR")
}
entity.SignIdentity(usrIdstring, entity, nil)
var copy = entity
var asciiSignedKey = PubEntToAsciiArmor(copy)
fmt.Println(asciiSignedKey)
}

1.) When I serialize the public key (to get an armored version of it), I get the following error message:
> Serializing PubKey openpgp: invalid argument: Signature: need to call Sign, SignUserId or SignKey before Serialize

I thought I just used every possible way to create a signature on that key?

2.) I still receive an output from problem 1, when I upload the key to a keyserver, than the available information are incomplete. Only the key-id and the creation date are listed. All additional information like, self-signature, user-id-string and so on are missing (example: https://pgp.mit.edu/pks/lookup?search=0xbe6ee21e94a73ba5&op=index). What went wrong? Is it related to error 1?

PS: I am new to golang, started today.

答案1

得分: 2

也许这段代码可以满足你的需求。免责声明:我不是openpgp的专家,我不知道这是否正确。但是它可以与gpg --import一起使用。

package main

import (
	"fmt"
	"os"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
)

func main() {
	var e *openpgp.Entity
	e, err := openpgp.NewEntity("itis", "test", "itis@itis3.com", nil)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 在这里添加更多的身份信息

	// 对所有身份进行签名
	for _, id := range e.Identities {
		err := id.SelfSignature.SignUserId(id.UserId.Id, e.PrimaryKey, e.PrivateKey, nil)
		if err != nil {
			fmt.Println(err)
			return
		}
	}

	w, err := armor.Encode(os.Stdout, openpgp.PublicKeyType, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer w.Close()

	e.Serialize(w)
}

希望对你有帮助!

英文:

Maybe this will do what you want. Disclaimer: I am not an expert in openpgp; I don't know whether this is correct or not. But it does work with gpg --import.

package main
import (
"fmt"
"os"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
)
func main() {
var e *openpgp.Entity
e, err := openpgp.NewEntity("itis", "test", "itis@itis3.com", nil)
if err != nil {
fmt.Println(err)
return
}
// Add more identities here if you wish
// Sign all the identities
for _, id := range e.Identities {
err := id.SelfSignature.SignUserId(id.UserId.Id, e.PrimaryKey, e.PrivateKey, nil)
if err != nil {
fmt.Println(err)
return
}
}
w, err := armor.Encode(os.Stdout, openpgp.PublicKeyType, nil)
if err != nil {
fmt.Println(err)
return
}
defer w.Close()
e.Serialize(w)
}

答案2

得分: 2

这似乎是一个已知的问题:https://github.com/golang/go/issues/6483。解决方法是先调用SerializePrivate,即使你不使用结果。

英文:

This seems to be a known issue: https://github.com/golang/go/issues/6483. The workaround is to call SerializePrivate first, even if you don't use the result.

答案3

得分: 2

我为了这个目的编写了https://github.com/alokmenghrajani/gpgeez。这是一个Go库,可以更轻松地进行密钥创建或将密钥导出为装甲字符串。

以下是简要的代码,没有进行任何错误检查:

func CreateKey() *openpgp.Entity {
  key, _ := openpgp.NewEntity(name, comment, email, nil)

  for _, id := range key.Identities {
    id.SelfSignature.PreferredSymmetric = []uint8{...}    
    id.SelfSignature.PreferredHash = []uint8{...}    
    id.SelfSignature.PreferredCompression = []uint8{...}

    id.SelfSignature.SignUserId(id.UserId.Id, key.PrimaryKey, key.PrivateKey, nil)
  }

  // 自签名子密钥
  for _, subkey := range key.Subkeys {
    subkey.Sig.SignKey(subkey.PublicKey, key.PrivateKey, nil)
  }

  return r
}

这段代码可以帮助你更轻松地创建和导出密钥。

英文:

I wrote https://github.com/alokmenghrajani/gpgeez for exactly this purpose. It's a Go library which makes things like key creating or exporting a key as an armored string easier.

Here is the gist of it, without any error checking:

func CreateKey() *openpgp.Entity {
key, _ := openpgp.NewEntity(name, comment, email, nil)
for _, id := range key.Identities {
id.SelfSignature.PreferredSymmetric = []uint8{...}    
id.SelfSignature.PreferredHash = []uint8{...}    
id.SelfSignature.PreferredCompression = []uint8{...}
id.SelfSignature.SignUserId(id.UserId.Id, key.PrimaryKey, key.PrivateKey, nil)
}
// Self-sign the Subkeys
for _, subkey := range key.Subkeys {
subkey.Sig.SignKey(subkey.PublicKey, key.PrivateKey, nil)
}
return r
}

huangapple
  • 本文由 发表于 2015年4月29日 04:55:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/29929750.html
匿名

发表评论

匿名网友

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

确定