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

Go生成可被Java SHA256withDSA验签的签名问题咨询

问题根因

  • 当前Go代码的私钥解析逻辑错误:使用ssh.ParseRawPrivateKey解析标准PKCS#1格式的DSA私钥,解析得到的私钥参数异常,直接导致签名结果错误。
  • Go标准库的crypto/dsa包已被官方废弃,仅支持FIPS 186-2标准(1024位密钥+SHA1哈希),无法兼容SHA256withDSA(对应FIPS 186-3及以上标准)的签名要求。

问题1:如何生成可被Java SHA256withDSA验签的签名

方案A:优先替换为ECDSA算法(推荐)

DSA算法已逐步被ECDSA替代,Go和Java的标准库均原生支持SHA256withECDSA,跨语言兼容无任何问题,改动成本极低。

方案B:必须使用DSA的修正步骤

  1. 替换私钥解析逻辑:使用encoding/pem和crypto/x509标准库解析PEM格式私钥,不要使用SSH相关的解析函数。
  2. 替换DSA实现:使用支持FIPS 186-3标准的第三方DSA库,不要使用标准库的crypto/dsa。

修正后的Go代码示例:

package main

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/x509"
	"encoding/asn1"
	"encoding/hex"
	"encoding/pem"
	"fmt"
	"math/big"

	"github.com/cloudflare/cfssl/crypto/dsa"
)

func main() {
	pemData := []byte("-----BEGIN DSA PRIVATE KEY-----\n" +
		"MIIBvAIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR\n" +
		"+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb\n" +
		"+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg\n" +
		"UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX\n" +
		"TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj\n" +
		"rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB\n" +
		"TDv+z0kqAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJGrcxHiN2sW8IztEbqrKKiMxp\n" +
		"NlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowWWVRdhdFXZlpCyp1gMWqJ11dh\n" +
		"3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6y8DPH4/4EBT7KvnVAhR4Vwun\n" +
		"Fhu/+4AGaVeMEa814I3dqg==\n" +
		"-----END DSA PRIVATE KEY-----")

	// 修正私钥解析逻辑
	block, _ := pem.Decode(pemData)
	pp, err := x509.ParseDSAPrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}

	// 计算原始数据的SHA256哈希
	rawData := []byte{1}
	hasher := sha256.New()
	hasher.Write(rawData)
	hashed := hasher.Sum(nil)

	// 用支持SHA256的第三方DSA库签名
	r, s, err := dsa.Sign(rand.Reader, pp, hashed)
	if err != nil {
		panic(err)
	}

	// 编码为ASN1格式,和Java侧要求的签名格式对齐
	type dsaSignature struct {
		R, S *big.Int
	}
	signatureBytes, _ := asn1.Marshal(dsaSignature{R: r, S: s})
	fmt.Println(hex.EncodeToString(signatureBytes))
}

上述代码生成的签名可直接被你提供的Java验签代码校验通过。


问题2:支持该需求的Go第三方库

首推github.com/cloudflare/cfssl/crypto/dsa:Cloudflare开源的CFSSL工具库中的DSA实现,完整支持FIPS 186-3标准,兼容SHA256withDSA的签名验签逻辑,和Java端的标准实现完全对齐。


内容的提问来源于stack exchange,提问作者TBC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:00:02