emmansun / gmsm

ShangMi (SM) cipher suites for golang (Go语言商用密码软件)

Home Page:https://emmansun.github.io/gmsm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

when the public and private keys of sm2 are converted into hexadecimal strings, the length is not 64

jan-bar opened this issue · comments

commented

This is the answer to the public and private key length given by GPT

image

This is a website that generates sm2 public and private keys online:https://const.net.cn/tool/sm2/genkey/

An online sm2 encryption and decryption website:https://webencrypt.org/sm2samplecryptjs/

This is my test program

package main

import (
	"crypto/rand"
	"fmt"

	"github.com/emmansun/gmsm/sm2"
)

func main() {
	for {
		sm2Pri, err := sm2.GenerateKey(rand.Reader)
		if err != nil {
			panic(err)
		}

		privateKey := sm2Pri.D.Bytes()
		if len(privateKey) != 32 {
			fmt.Printf("privateKey len:[%d]\n", len(privateKey))
			break
		}

		publicKey := append(sm2Pri.X.Bytes(), sm2Pri.Y.Bytes()...)
		if len(publicKey) != 64 {
			fmt.Printf("publicKey len:[%d]\n", len(publicKey))
			break
		}
	}
}

As a result, the length of the public and private keys always does not meet the requirements, causing the generated public and private keys to be unusable in other programming languages.

  • 这是两个不同的概念,这里的私钥中的D,公钥中的X,Y是*big.Int类型,其Bytes()方法返回其实际使用字节数,因为创建big.Int时,已经对其规范化,其高字节0已经去除,不计字节数。
  • 和其它语言、系统互操作也有一个把公私钥规范化输出的过程,譬如公钥的PKIX, ASN.1 DER form,私钥的PKCS8、SEC1格式等等。
  • 没有哪个规范指明生成的私钥,其最高字节不能为0,如果有(譬如SM2私钥生成规范)请告知。现在的方法和Go语言的方法(NIST P系列曲线的ECDSA/ECDH)是一致的。如果用于签名、加密,使用sm2包下的GenerateKey方法;如果用于ECDH,则建议使用ECDH包下的GenerateKey方法。
commented

@emmansun 我现在需要对外提供十六进制的字符串公私钥,因为网上找到的一些文档和Python和js的库都用十六进制字符串表示公私钥,我试试在长度不足时高位补零看看行不行。不行就只能写个循环,生成的不合法则继续生成,直到成功 😭

  1. 不建议使用这种方式传输私钥。
  2. big.Int可以使用FillBytes方法输出值到固定长度字节。
func toBytes(curve elliptic.Curve, value *big.Int) []byte {
	byteLen := (curve.Params().BitSize + 7) >> 3
	result := make([]byte, byteLen)
	value.FillBytes(result)
	return result
}
commented

@emmansun 我也想用smx509里面的方法啊(我自测就是用这个),现在要对接第三方,人家不认,领导要我改成通用格式,我们另一个部门用的C++,应该是用的C库,也是要这种十六进制的公私钥。 😭

感谢大佬提供思路 👍