Go语言的sm2加密算法封装

随机生成公私钥

// CreateSM2Key
/** 
 *  @Description: 随机生成公私钥
 *  @return privateKey
 *  @return publicKey
 *  @return err
 */
func CreateSM2Key()(privateKey *sm2.PrivateKey,publicKey *sm2.PublicKey,err error) {
	// 生成sm2秘钥对
	privateKey, err = sm2.GenerateKey(rand.Reader)
	if err != nil {
		return 
	}
	// 进行sm2公钥断言
	publicKey = privateKey.Public().(*sm2.PublicKey)
	return 
}

创建私钥文件

// CreatePrivatePem
/** 
 *  @Description: 创建私钥文件
 *  @param privateKey 私钥
 *  @param pwd 私钥密码
 *  @param path 生成的私钥文件路径
 *  @return err
 */
func CreatePrivatePem(privateKey *sm2.PrivateKey, pwd []byte, path string) (err error) {
	// 将私钥反序列化并进行pem编码
	var privateKeyToPem []byte
	privateKeyToPem, err = x509.WritePrivateKeyToPem(privateKey, pwd)
	if err != nil {
		return err
	}
	// 将私钥写入磁盘
	if path == "" {
		path = "cert/sm2Private.Pem"
	}
	// 获取文件中的路径
	paths, _ := filepath.Split(path)
	err = os.MkdirAll(paths, os.ModePerm)
	if err != nil {
		return err
	}
	var file *os.File
	file, err = os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.Write(privateKeyToPem)
	if err != nil {
		return err
	}
	return
}

创建公钥文件

// CreatePublicPem
/** 
 *  @Description: 创建公钥文件
 *  @param publicKey 公钥
 *  @param path 生成的公钥文件路径
 *  @return err
 */
func CreatePublicPem(publicKey *sm2.PublicKey, path string) (err error) {
	// 将私钥反序列化并进行pem编码
	var publicKeyToPem []byte
	publicKeyToPem, err = x509.WritePublicKeyToPem(publicKey)
	if err != nil {
		return err
	}
	// 将私钥写入磁盘
	if path == "" {
		path = "cert/sm2Public.Pem"
	}
	// 获取文件中的路径
	paths, _ := filepath.Split(path)
	err = os.MkdirAll(paths, os.ModePerm)
	if err != nil {
		return err
	}
	var file *os.File
	file, err = os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.Write(publicKeyToPem)
	if err != nil {
		return err
	}
	return
}

读取私钥文件

// ReadPrivatePem
/** 
 *  @Description: 读取私钥文件 
 *  @param path 私钥文件路径
 *  @param pwd 私钥文件密码,无则填nil
 *  @return privateKey 私钥
 *  @return err
 */
func ReadPrivatePem(path string, pwd []byte) (privateKey *sm2.PrivateKey, err error) {
	// 打开文件读取私钥
	var file *os.File
	file, err = os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	var fileInfo os.FileInfo
	fileInfo, err = file.Stat()
	if err != nil {
		return nil, err
	}
	buf := make([]byte, fileInfo.Size(), fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		return nil, err
	}
	// 将pem格式私钥文件进行反序列化
	privateKey, err = x509.ReadPrivateKeyFromPem(buf, pwd)
	if err != nil {
		return nil, err
	}
	return
}

读取公钥文件

// ReadPublicPem
/** 
 *  @Description: 读取公钥文件
 *  @param path 公钥文件路径
 *  @return publicKey 公钥文件
 *  @return err 
 */
func ReadPublicPem(path string) (publicKey *sm2.PublicKey, err error) {
	// 打开文件读取私钥
	var file *os.File
	file, err = os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	var fileInfo os.FileInfo
	fileInfo, err = file.Stat()
	if err != nil {
		return nil, err
	}
	buf := make([]byte, fileInfo.Size(), fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		return nil, err
	}
	// 将pem格式私钥文件进行反序列化
	publicKey, err = x509.ReadPublicKeyFromPem(buf)
	if err != nil {
		return nil, err
	}
	return
}

SM2加密(公钥加密)

// Encrypt
/** 
 *  @Description: SM2加密(公钥加密)
 *  @param data 需要加密的数据
 *  @param publicKey 公钥
 *  @return cipherStr 加密后的字符串
 */
func Encrypt(data string, publicKey *sm2.PublicKey) (cipherStr string) {
	// 将字符串转为[]byte
	dataByte := []byte(data)
	// sm2加密
	cipherTxt, err := publicKey.EncryptAsn1(dataByte, rand.Reader)
	if err != nil {
		log.Fatal(err)
	}
	// 转为16进制字符串输出
	//cipherStr = fmt.Sprintf("%x", cipherTxt)
	cipherStr = hex.EncodeToString(cipherTxt)
	return
}

SM2解密(私钥解密)

// Decode
/** 
 *  @Description: SM2解密(私钥解密)
 *  @param cipherStr 加密后的字符串
 *  @param privateKey 私钥
 *  @return data 解密后的数据
 *  @return err
 */
func Decode(cipherStr string, privateKey *sm2.PrivateKey) (data string, err error) {
	// 16进制字符串转[]byte
	bytes, _ := hex.DecodeString(cipherStr)
	// sm2解密
	var dataByte []byte
	dataByte, err = privateKey.DecryptAsn1(bytes)
	if err != nil {
		return data, err
	}
	// byte数组直接转成string,优化内存
	str := (*string)(unsafe.Pointer(&dataByte))
	return *str, err
}

SM2签名

// Sign
/** 
 *  @Description: 签名
 *  @param msg 需要签名的内容
 *  @param privateKey 私钥
 *  @param signer
 *  @return sign
 *  @return err
 */
func Sign(msg string, privateKey *sm2.PrivateKey, signer crypto.SignerOpts) (sign string, err error) {
	dataByte := []byte(msg)
	var signByte []byte
	// sm2签名
	signByte, err = privateKey.Sign(rand.Reader, dataByte, signer)
	if err != nil {
		return "", err
	}
	// 转为16进制字符串输出
	sign = hex.EncodeToString(signByte)
	return sign, nil
}

SM2验签

// Verify
/**
 *  @Description: 验签
 *  @param msg 需要验签的内容
 *  @param sign 验签
 *  @param publicKey 公钥
 *  @return verify
 */
func Verify(msg, sign string, publicKey *sm2.PublicKey) (verify bool) {
	// 16进制字符串转[]byte
	msgBytes := []byte(msg)
	signBytes, _ := hex.DecodeString(sign)
	// sm2验签
	verify = publicKey.Verify(msgBytes, signBytes)
	return
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值