douan0729 2015-04-28 20:55
浏览 125
已采纳

Go-Golang openpg-创建密钥对并创建签名

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.

  • 写回答

3条回答 默认 最新

  • dongquan6030 2015-04-29 15:56
    关注

    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条)

报告相同问题?

悬赏问题

  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形