目录

1、概述

  SM国密算法是指国家密码局认定的「国产商用密码算法」,包括(不止):

  • SM1、SM4、SM7、祖冲之密码(ZUC)是对称算法,其中SM1、SM7算法不公开,调用该算法时,需要通过加密芯片的接口进行调用
  • SM2、SM9是非对称算法
  • SM3是哈希算法。

  目前主要使用公开的SM2、SM3、SM4三类算法,分别是非对称算法、哈希算法和对称算法。

image-1691499368637

2、分类

2.1 SM1算法

   SM1 算法是分组密码算法,分组长度为128位,密钥长度都为 128 比特,算法安全保密强度及相关软硬件实现性能与 AES 相当,算法不公开,仅以IP核的形式存在于芯片中。

   采用该算法已经研制了系列芯片、智能IC卡、智能密码钥匙、加密卡、加密机等安全产品,广泛应用于电子政务、电子商务及国民经济的各个应用领域(包括国家政务通、警务通等重要领域)。

  

2.2 SM2算法

   SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,采用ECC椭圆曲线密码机制,但在签名、密钥交换方面不同于ECDSA、ECDH等国际标准。

   SM2包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。

   SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高。

   在实际使用中,国密局推荐使用素数域256 位椭圆曲线,其曲线方程为y^2= x^3+ax+b(其中p是大于3的一个大素数,n是基点G的阶,Gx、Gy 分别是基点G的x与y值,a、b是随圆曲线方程y^2= x^3+ax+b的系数)。

  

2.3 SM3算法

   SM3哈希算法是我国自主设计的密码哈希算法,适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。

   为了保证哈希算法的安全性,其产生的哈希值的长度不应太短,例如MD5输出128比特哈希值,输出长度太短,影响其安全性,SHA-1算法的输出长度为160比特,SM3算法的输出长度为256比特,因此SM3算法的安全性要高于MD5算法和SHA-1算法。

  

2.4 SM4算法

   SM4分组密码算法是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。

   要保证一个对称密码算法的安全性的基本条件是其「具备足够的密钥长度」,SM4算法与AES算法具有相同的密钥长度分组长度128比特,因此在安全性上高于3DES算法。

  

2.5 SM7算法

   SM7算法,是一种分组密码算法,分组长度为128比特,密钥长度为128比特。

   SM7适用于非接触式IC卡,应用包括身份识别类应用(门禁卡、工作证、参赛证),票务类应用(大型赛事门票、展会门票),支付与通卡类应用(积分消费卡、校园一卡通、企业一卡通等)。

  

2.6 SM9算法

     SM9标识密码算法不需要申请数字证书,标识密码将用户的标识(如邮件地址、手机号码、QQ号码等)作为公钥,省略了交换数字证书和公钥过程,使得安全系统变得易于部署和管理,非常适合端对端离线安全通讯、云端数据加密、基于属性加密、基于策略加密的各种场合。

  

2.7 ZUC算法

   ZUC祖冲之算法是中国自主研究的流密码算法,是运用于移动通信4G网络中的国际标准密码算法,该算法包括祖冲之算法(ZUC)、加密算法(128-EEA3)和完整性算法(128-EIA3)三个部分。
  

3、代码测试(Go)

go get -u github.com/tjfoc/gmsm

main.go

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"github.com/tjfoc/gmsm/sm2"
	"github.com/tjfoc/gmsm/sm3"
	"log"
)

func main()  {
	service.SM3()
	service.SM2()
}

func SM2 (){
	content := []byte("hello world")
	priv, err := sm2.GenerateKey(rand.Reader) // 生成密钥对
	if err != nil {
		log.Fatal(err)
	}
	pub := &priv.PublicKey
	ciphertxt, err := pub.EncryptAsn1(content,rand.Reader) //sm2加密
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("加密结果: ",ciphertxt)

	plaintxt,err :=  priv.DecryptAsn1(ciphertxt)  //sm2解密
	if err != nil {
		log.Fatal(err)
	}
	if !bytes.Equal(content,plaintxt){
		log.Fatal("原文不匹配")
	}

	sign,err := priv.Sign(rand.Reader, content, nil)  //sm2签名
	if err != nil {
		log.Fatal(err)
	}
	isok := pub.Verify(content, sign)    //sm2验签
	fmt.Printf("Verified: %v\n", isok)

}

func SM3(){
	content := []byte("hello world")
	h := sm3.New()
	h.Write([]byte(content))
	sum := h.Sum(nil)
	fmt.Printf("sm3 value is: %x\n",sum)
}

 
参考链接:
https://blog.csdn.net/ws_kfxd/article/details/105650876
https://zhuanlan.zhihu.com/p/89791842

如有不对,烦请指出,感谢!