无法使用golang';对有效的gpg密钥进行签名;s openpgp数据包

无法使用golang';对有效的gpg密钥进行签名;s openpgp数据包,go,digital-signature,gnupg,Go,Digital Signature,Gnupg,我想用go语言中的私钥对ascii armor中的公钥进行签名。为此,我开发了以下代码,但问题是当我在gpg中检查签名时——检查签名代码创建的签名显示为“坏签名”.请帮忙,因为我想不出任何解决办法。我已经在golang nuts上发了帖子。我只是为了我的大学项目学习golang,我被困在这里,请帮忙 // signer package main import ( "bytes" "code.google.com/p/go.crypto/openpgp" "cod

我想用go语言中的私钥对ascii armor中的公钥进行签名。为此,我开发了以下代码,但问题是当我在gpg中检查签名时——检查签名代码创建的签名显示为“坏签名”.请帮忙,因为我想不出任何解决办法。我已经在golang nuts上发了帖子。我只是为了我的大学项目学习golang,我被困在这里,请帮忙

    // signer
package main

import (
    "bytes"
    "code.google.com/p/go.crypto/openpgp"
    "code.google.com/p/go.crypto/openpgp/armor"
    "code.google.com/p/go.crypto/openpgp/packet"
    "fmt"
)

// This function takes asciiarmored private key which will sign the public key
//Public key is also ascii armored,pripwd is password of private key in string
//This function will return ascii armored signed public key i.e. (pubkey+sign by prikey)
func SignPubKeyPKS(asciiPub string, asciiPri string, pripwd string) (asciiSignedKey string) {
    //get Private key from armor
    _, priEnt := getPri(asciiPri, pripwd) //pripwd is the password todecrypt the private key
    _, pubEnt := getPub(asciiPub)         //This will generate signature and add it to pubEnt
    usrIdstring := ""
    for _, uIds := range pubEnt.Identities {
        usrIdstring = uIds.Name

    }
    fmt.Println(usrIdstring)
    errSign := pubEnt.SignIdentity(usrIdstring, &priEnt, nil)
    if errSign != nil {
        fmt.Println("Signing Key ", errSign.Error())
        return
    }
    asciiSignedKey = PubEntToAsciiArmor(pubEnt)
    return
}

//get packet.PublicKey and openpgp.Entity of Public Key from ascii armor
func getPub(asciiPub string) (pubKey packet.PublicKey, retEntity openpgp.Entity) {
    read1 := bytes.NewReader([]byte(asciiPub))
    entityList, errReadArm := openpgp.ReadArmoredKeyRing(read1)
    if errReadArm != nil {
        fmt.Println("Reading Pubkey ", errReadArm.Error())
        return
    }
    for _, pubKeyEntity := range entityList {
        if pubKeyEntity.PrimaryKey != nil {
            pubKey = *pubKeyEntity.PrimaryKey
            retEntity = *pubKeyEntity
        }
    }
    return
}

//get packet.PrivateKEy and openpgp.Entity of Private Key from ascii armor
func getPri(asciiPri string, pripwd string) (priKey packet.PrivateKey, priEnt openpgp.Entity) {
    read1 := bytes.NewReader([]byte(asciiPri))
    entityList, errReadArm := openpgp.ReadArmoredKeyRing(read1)
    if errReadArm != nil {
        fmt.Println("Reading PriKey ", errReadArm.Error())
        return
    }
    for _, can_pri := range entityList {
        smPr := can_pri.PrivateKey
        retEntity := can_pri
        if smPr == nil {
            fmt.Println("No Private Key")
            return
        }

        priKey = *smPr

        errDecr := priKey.Decrypt([]byte(pripwd))
        if errDecr != nil {
            fmt.Println("Decrypting ", errDecr.Error())
            return
        }
        retEntity.PrivateKey = &priKey
        priEnt = *retEntity
    }
    return
}

//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
}

代码看起来大致正常,只是错误检查应该更加严格。对错误惊慌失措比根本不检查错误要好(因为它通常会在以后出现故障)

问题在于
code.google.com/p/go.crypto/openpgp
内部的
Signature.SignUserId()
的实现是错误的。它使用对密钥进行签名的算法(用于证明子密钥属于主键),而不是对用户id进行签名的算法

此外,在探索这一点时,我意识到,
PublicKey.VerifyUserIdSignature()
的实现方式仅适用于自签名用户ID,因为它在散列中没有使用正确的公钥


错误报告,带有补丁

感谢回复,很抱歉我忙于考试,因此无法回复。我还指出了go的openpgp/装甲输出中的装甲差异,它包含正确的代码。再次感谢pin指出问题的原因。同时,请检查go的openpgp/装甲输出中的装甲差异