You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:30:00