使用Go语言用DSA对SHA-256哈希进行签名。

huangapple go评论85阅读模式
英文:

sign a SHA-256 hash with DSA in Go

问题

我想用DSA对SHA-256哈希进行签名。

使用Java,我可以这样写:

 Signature sig = Signature.getInstance("SHA256withDSA");
 sig.initSign(priKey);
 sig.update(new byte[]{1});
 byte[] sign = sig.sign();
 System.out.println(HexUtil.encodeHexStr(sign));

使用Go语言,我找不到任何解决方法。

英文:

I want to sign a SHA-256 hash with DSA.

Using Java I can write:

 Signature sig = Signature.getInstance("SHA256withDSA");
 sig.initSign(priKey);
 sig.update(new byte[]{1});
 byte[] sign = sig.sign();
 System.out.println(HexUtil.encodeHexStr(sign));

Using the Go language, I couldn't find any way to resolve it

答案1

得分: 2

在Go语言中,对DSAWithSHA256签名的唯一检查实例出现在github.com/avast/apkverifier中的代码中。

    case x509.DSAWithSHA256:
		hash := sha256.Sum256(signed)
		pub := cert.PublicKey.(*dsa.PublicKey)
		reqLen := pub.Q.BitLen() / 8
		if reqLen > len(hash) {
			return fmt.Errorf("给定的DSA参数对应的摘要算法太短。")
		}
		digest := hash[:reqLen]

		dsaSig := new(dsaSignature)
		if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil {
			return err
		} else if len(rest) != 0 {
			return errors.New("x509: DSA签名后存在多余数据")
		}
		if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
			return errors.New("x509: DSA签名包含零值或负值")
		}
		if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
			return errors.New("x509: DSA验证失败")
		}

但实际上,在github.com/grantae/certinfo中有说明,确实不支持使用该签名算法。

> ## 问题:
>
> 1. 不幸的是,OpenSSL对DSA和ECDSA证书请求使用非确定性签名,因此运行make-certs.sh将无法生成相同的CSR,尽管密钥是静态的。
这些文件必须手动保持同步。
>
> 2. x509包目前不会为DSA CSR设置CertificateRequest.SignatureAlgorithm
因此,'leaf2.csr.text'文件中包含的行是'Signature Algorithm: 0',而不是'Signature Algorithm: DSAWithSHA256',以便测试通过并指示问题出现在x509而不是该包中。

因此,在Go的crypto/x509包中,该签名算法是不支持的

英文:

The only instance of checking a DSAWithSHA256 signature in go is in github.com/avast/apkverifier

    case x509.DSAWithSHA256:
		hash := sha256.Sum256(signed)
		pub := cert.PublicKey.(*dsa.PublicKey)
		reqLen := pub.Q.BitLen() / 8
		if reqLen &gt; len(hash) {
			return fmt.Errorf(&quot;Digest algorithm is too short for given DSA parameters.&quot;)
		}
		digest := hash[:reqLen]

		dsaSig := new(dsaSignature)
		if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil {
			return err
		} else if len(rest) != 0 {
			return errors.New(&quot;x509: trailing data after DSA signature&quot;)
		}
		if dsaSig.R.Sign() &lt;= 0 || dsaSig.S.Sign() &lt;= 0 {
			return errors.New(&quot;x509: DSA signature contained zero or negative values&quot;)
		}
		if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
			return errors.New(&quot;x509: DSA verification failure&quot;)
		}

But actually using the signature algorithm is indeed unsupported, for reason illustrated in github.com/grantae/certinfo

> ## Issues:
>
> 1. Unfortunately, OpenSSL uses non-deterministic signing for DSA and ECDSA certificate requests, so running make-certs.sh will not reproduce the same CSRs despite having static keys.
These files have to be kept in-sync manually.
>
> 2. The x509 package does not currently set CertificateRequest.SignatureAlgorithm for DSA CSRs.
Therefore the 'leaf2.csr.text' contains the line 'Signature Algorithm: 0'
instead of 'Signature Algorithm: DSAWithSHA256' to allow the test to pass and indicate that the problem is with x509 and not this package.

Hence its unsupported status in Go crypto/x509 package.

huangapple
  • 本文由 发表于 2021年8月31日 12:32:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/68992914.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定