我想用go语言的私有密钥用ascii盔甲签名一个公共密钥。为此,我开发了以下代码,但问题是当我在gpg --check-sigs中检查签名时,由代码创建的签名显示为“坏签名”。请帮忙,因为我找不到解决方法。我已经在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
}
该代码看起来大致上还可以,只是它在错误检查方面确实应该更加严格。对错误进行恐慌总比不进行任何错误检查要好(因为它通常会在以后出现段错误)。
问题在于,Signature.SignUserId()
内部实现code.google.com/p/go.crypto/openpgp
是错误的。它使用的是对密钥进行签名的算法(用于证明子密钥属于主密钥),而不是对用户ID进行签名的算法。
此外,在探索这一点时,我意识到该PublicKey.VerifyUserIdSignature()
实现方式仅适用于自签名用户ID,因为它未在哈希中使用正确的公钥。
错误报告,带有修补程序https://code.google.com/p/go/issues/detail?id=7371
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句