银联联机UTVTSM4MAC算法的Go语言实现

参考文档

https://wenku.baidu.com/view/903df10e3269a45177232f60ddccda38376be1d9.html

安装

go get github.com/tjfoc/gmsm

代码

package sm4

import (
	"encoding/hex"
	"fmt"
	"github.com/pkg/errors"
	"github.com/tjfoc/gmsm/sm4"
)

// utvtSm4Mac
/**
 *  @Description: 银联联机UtvtSm4Mac算法
 *  @param mab 需要加密的内容
 *  @param key 密码
 *  @return secretText 加密后的内容
 *  @return err
 */
func utvtSm4Mac(mab string, key []byte) (secretText string, err error) {
	// 创建一个Sm4Cipher
	c, err := sm4.NewCipher(key)
	if err != nil {
		return
	}
	// SM4算法的MAB,按每16个字节做异或(不管信息中的字符格式),如果最后不满16个字节,则添加“0X00”。
	l := len(mab) % 16
	mabByte := []byte(mab)
	for i := 0; i < 16-l; i++ {
		mabByte = append(mabByte, 0x00)
	}
	resultBlock := make([]byte, 16, 16)
	for i := 0; i < len(mabByte)/16-1; i++ {
		var byteXorErr error
		if i == 0 {
			resultBlock, byteXorErr = byteXor(mabByte[:16], mabByte[16:32])
		} else {
			resultBlock, byteXorErr = byteXor(mabByte[i*16:i*16+16], resultBlock)
		}
		if byteXorErr != nil {
			err = byteXorErr
			return
		}
	}
	// 将异或运算后的最后16个字节(RESULT BLOCK)转换成32 个HEXDECIMAL
	resultBlockStr := hex.EncodeToString(resultBlock)
	resultBlockByte := []byte(resultBlockStr)
	// 取前16个字节用SM4加密
	encBlock1 := make([]byte, 16)
	c.Encrypt(encBlock1, resultBlockByte[:16])
	// 将加密后的结果与后16个字节异或
	tempBlock, byteXorErr := byteXor(encBlock1, resultBlockByte[16:])
	if byteXorErr != nil {
		err = byteXorErr
		return
	}
	// 用异或的结果TEMP BLOCK 再进行一次SM4密钥算法运算。
	encBlock2 := make([]byte, 16)
	c.Encrypt(encBlock2, tempBlock)
	// 将运算后的结果(ENC BLOCK2)转换成32 个HEXDECIMAL
	// 取前8个字节作为硬件序列号加密数据
	//encResult := hex.EncodeToString(encBlock2)
	secretText = fmt.Sprintf("%X", encBlock2)[:8]
	return
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值