生成国密证书sm2证书

Posted 小米渣的逆袭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成国密证书sm2证书相关的知识,希望对你有一定的参考价值。

最近使用开源项目tjfoc/gmsm 做国密研究,由于他没有具体说怎么生成证书的,期间对于生成他对应的国密证书做了些研究,踩了一些坑

他对国密通信做的demo主要在websvr目录下

 

下面主要说下生成国密证书步骤

1. 需要装gmssl , 具体编译参见上一篇文章

2. 使用gmssl ecparam -genkey -name sm2p256v1 -noout -out $OUTPUT/$name.key 生成的私钥在他的go代码 gmtls.LoadX509KeyPair 方法会报错,经过研究可以使用x509目录下的go生成私钥

所以使用x509目录下的生成私钥代码

 

func createPrvateKey(s string)  
	priv, err := sm2.GenerateKey(nil) // 生成密钥对
	if err != nil 
		return
	
	privPem, err := WritePrivateKeyToPem(priv, nil) // 生成密钥文件
	fmt.Printf("privateKey=%s",privPem)
	if err != nil 
		return
	
	os.Remove(s)
	os.WriteFile(s,privPem,0666)

其他部分还是使用gmssl生成

rootPath=$(cd "$(dirname "$0")"; pwd)
#删除打包数据目录
OUTPUT=$rootPath/build
rm -drf $OUTPUT
mkdir $OUTPUT 

# 生成CA证书
echo "-----------------------------生成CA证书----------------------------------"
name="ca"
cp -R /Users/wjr/Downloads/$name.key $OUTPUT/$name.key
#gmssl ecparam -genkey -name sm2p256v1 -noout -out $OUTPUT/$name.key 
gmssl req -new -SM3 -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
gmssl x509 -req -days 3650 -sm3 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_ca -signkey $OUTPUT/$name.key -out $OUTPUT/$name.cer
gmssl x509 -in $OUTPUT/$name.cer -text -noout  



echo "-----------------------------Server签名证书----------------------------------"
# Server签名证书
name="server_sign"
cp -R /Users/wjr/Downloads/$name.key $OUTPUT/$name.key
#gmssl ecparam -name sm2p256v1 -genkey -noout -out $OUTPUT/$name.key
gmssl req -new -SM3 -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
gmssl x509 -req -SM3 -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_req -CA $OUTPUT/ca.cer -CAkey $OUTPUT/ca.key -set_serial 1000000001 -extfile $rootPath/openssl.cnf -out $OUTPUT/$name.cer  
gmssl x509 -in $OUTPUT/$name.cer -text -noout  


echo "-----------------------------Server加密证书----------------------------------"
# Server加密证书
name="server_encode"
cp -R /Users/wjr/Downloads/$name.key $OUTPUT/$name.key
#gmssl ecparam -name sm2p256v1 -genkey -noout -out $OUTPUT/$name.key
gmssl req -new -SM3 -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
gmssl x509 -req -SM3 -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3enc_req -CA $OUTPUT/ca.cer -CAkey $OUTPUT/ca.key -set_serial 1000000001 -extfile openssl.cnf -out $OUTPUT/$name.cer  
gmssl x509 -in $OUTPUT/$name.cer -text -noout  


echo "-----------------------------客户端证书----------------------------------"
# 客户端证书
name="client"
cp -R /Users/wjr/Downloads/$name.key $OUTPUT/$name.key
#gmssl ecparam -name sm2p256v1 -genkey -noout -out $OUTPUT/$name.key
gmssl req -new -SM3 -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
gmssl x509 -req -SM3 -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_req -CA $OUTPUT/ca.cer -CAkey $OUTPUT/ca.key -set_serial 1000000001 -extfile openssl.cnf -out $OUTPUT/$name.cer  
gmssl x509 -in $OUTPUT/$name.cer -text -noout 
exit 0

3. 开始生成的证书会报keyUsage相关错误,以server签名证书为例

使用./openssl.cnf -extensions v3_req 参数,在openssl.cnf中

 server加密证书

-extfile ./openssl.cnf -extensions v3enc_req

4. 如果遇到 x509: cannot validate certificate for x.x.x.x because it doesn't contain any IP SANs 解决: 解决参考

在openssl.cnf中

 测试demo

func ServerRun() 
	config, err := loadSM2Config()
	if err != nil 
		panic(err)
	

	ln, err := gmtls.Listen("tcp", ":50052", config)
	if err != nil 
		log.Println(err)
		return
	
	defer ln.Close()
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) 
		fmt.Fprintf(writer, "王家荣\\n")
	)
	fmt.Println(">> HTTP Over [GMSSL/TLS] running...")
	err = http.Serve(ln, nil)
	if err != nil 
		panic(err)
	


func gmClientRun() 

	// 信任的根证书
	certPool := x509.NewCertPool()
	cacert, err := ioutil.ReadFile("./certs/ca.cer")
	//cacert, err := ioutil.ReadFile(SM2CaCertPath)
	if err != nil 
		log.Fatal(err)
	
	ok := certPool.AppendCertsFromPEM(cacert)
	if !ok 
		return
	
	//cert, err := gmtls.LoadX509KeyPair(sm2UserCertPath, sm2UserKeyPath)
	cert, err := gmtls.LoadX509KeyPair("./certs/client.cer", "./certs/client.key")
	if err != nil 
		log.Fatal(err)
	

	config := &gmtls.Config
		GMSupport:    &gmtls.GMSupport,
		RootCAs:      certPool,
		Certificates: []gmtls.Certificatecert,
		//InsecureSkipVerify: true,
	

	conn, err := gmtls.Dial("tcp", "127.0.0.1:50052", config)
	if err != nil 
		fmt.Printf("%s\\r\\n",err)
		return
	
	defer conn.Close()

	req := []byte("GET / HTTP/1.1\\r\\n" +
		"Host: 127.0.0.1\\r\\n" +
		"Connection: close\\r\\n\\r\\n")
	_, _ = conn.Write(req)
	buff := make([]byte, 1024)
	for 
		n, _ := conn.Read(buff)
		if n <= 0 
			break
		 else 
			fmt.Printf("收到回应[%s]\\r\\n", buff[0:n])
		
	
	fmt.Println(">> SM2_SM4_CBC_SM3 suite [PASS]")

	//	// 2. 提供客户端认证证书、密钥对。
	//clientAuthCert, err := gmtls.LoadX509KeyPair("./certs/sm2_auth_cert.cer", "./certs/sm2_auth_key.pem")
	 3. 构造HTTP客户端。
	//httpClient := gmtls.NewAuthHTTPSClient(certPool, &clientAuthCert)
	 4. 调用API访问HTTPS。
	//response, err := httpClient.Get("https://localhost:443")
	//if err != nil 
	//	panic(err)
	//
	//defer response.Body.Close()

 

以上是关于生成国密证书sm2证书的主要内容,如果未能解决你的问题,请参考以下文章

SM2国密证书合法性验证

gmssl国密总结

国密证书双向认证客户端发送哪个

SM2国密SSL证书为HTTPS加密提速

fabric国密改造记录及思路-具体工作(3)

gmssl国密证书生成方式:国密多级ca证书,国密加密证书,国密签名证书