如何在Go语言中使用DSA对SHA-256哈希值进行签名
Go 实现SHA256withDSA签名指引
Go 标准库原生支持该签名逻辑,和你给出的Java代码逻辑完全对齐,实现方式如下:
完整实现代码
package main import ( "crypto/dsa" "crypto/rand" "crypto/sha256" "crypto/x509" "encoding/asn1" "encoding/hex" "encoding/pem" "fmt" "math/big" ) // DSA签名ASN1序列化结构,和Java输出格式兼容 type dsaSignature struct { R, S *big.Int } func main() { // 1. 加载你的DSA私钥,此处替换为你自己的私钥加载逻辑 // 示例为读取PEM格式私钥内容 pemData := []byte(`你的PEM格式DSA私钥内容`) priKey, err := loadDSAPrivateKey(pemData) if err != nil { panic(err) } // 2. 待签名数据,对应Java代码中的new byte[]{1} data := []byte{1} // 3. 计算SHA256哈希,对应Java的update逻辑 hash := sha256.Sum256(data) // 4. 执行DSA签名 r, s, err := dsa.Sign(rand.Reader, priKey, hash[:]) if err != nil { panic(err) } // 5. 序列化为DER格式,和Java的签名输出格式完全一致 signBytes, err := asn1.Marshal(dsaSignature{R: r, S: s}) if err != nil { panic(err) } // 6. 输出十六进制格式签名 fmt.Println(hex.EncodeToString(signBytes)) } // loadDSAPrivateKey 加载PEM格式的DSA私钥 func loadDSAPrivateKey(pemData []byte) (*dsa.PrivateKey, error) { block, _ := pem.Decode(pemData) if block == nil || block.Type != "DSA PRIVATE KEY" { return nil, fmt.Errorf("无效的DSA私钥格式") } priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { // 如果是PKCS1格式私钥,替换为下方代码即可 // return x509.ParseDSAPrivateKey(block.Bytes) return nil, err } dsaPriKey, ok := priKey.(*dsa.PrivateKey) if !ok { return nil, fmt.Errorf("密钥不是DSA私钥类型") } return dsaPriKey, nil }
注意事项
- 签名输出的DER格式和Java
SHA256withDSA的输出完全兼容,两端验签可以互通 - 确保两端使用的DSA密钥参数完全一致,避免出现签名校验不通过的问题
内容的提问来源于stack exchange,提问作者TBC
相关产品推荐
相关产品推荐

