golang sm3、sm4 加密

sm3:

sm3.go

package sm3
import (
"hash"
)
//Size The size of a SM3 checksum in bytes.
const Size = 32
//BlockSize The blocksize of SM3 in bytes.
const BlockSize = 64
const (
chunk = 64
init0 = 0x7380166F
init1 = 0x4914B2B9
init2 = 0x172442D7
init3 = 0xDA8A0600
init4 = 0xA96F30BC
init5 = 0x163138AA
init6 = 0xE38DEE4D
init7 = 0xB0FB0E4E
)
// digest represents the partial evaluation of a checksum.
type digest struct {
h   [8]uint32
x   [chunk]byte
nx  int
len uint64
}
func (d *digest) Reset() {
d.h[0] = init0
d.h[1] = init1
d.h[2] = init2
d.h[3] = init3
d.h[4] = init4
d.h[5] = init5
d.h[6] = init6
d.h[7] = init7
d.nx = 0
d.len = 0
}
// New returns a new hash.Hash computing the SM3 checksum.
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
func (d *digest) Size() int { return Size }
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := copy(d.x[d.nx:], p)
d.nx += n
if d.nx == chunk {
block(d, d.x[:])
d.nx = 0
}
p = p[n:]
}
if len(p) >= chunk {
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:]
}
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
//Sum sum is add
func (d *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d1 := *d
hash := d1.checkSum()
return append(in, hash[:]...)
}
func (d *digest) checkSum() [Size]byte {
len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
d.Write(tmp[0 : 56-len%64])
} else {
d.Write(tmp[0 : 64+56-len%64])
}
// Length in bits.
len <<= 3
for i := uint(0); i < 8; i++ {
tmp[i] = byte(len >> (56 - 8*i))
}
d.Write(tmp[0:8])
if d.nx != 0 {
panic("d.nx != 0")
}
h := d.h[:]
var digest [Size]byte
for i, s := range h {
digest[i*4] = byte(s >> 24)
digest[i*4+1] = byte(s >> 16)
digest[i*4+2] = byte(s >> 8)
digest[i*4+3] = byte(s)
}
return digest
}
// Sum returns the SM3 checksum of the data.
func Sum(data []byte) [Size]byte {
var d digest
d.Reset()
d.Write(data)
return d.checkSum()
}

sm3block.go

package sm3
func block(dig *digest, p []byte) {
blockGeneric(dig, p)
}
func blockGeneric(dig *digest, p []byte) {
var w [68]uint32
var w1 [64]uint32
var ss1, ss2, tt1, tt2 uint32
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= chunk {
for i := 0; i < 16; i++ {
j := i * 4
w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
}
for i := 16; i < 68; i++ {
w[i] = sm3p1(w[i-16]^w[i-9]^sm3rotl(w[i-3], 15)) ^ sm3rotl(w[i-13], 7) ^ w[i-6]
}
for i := 0; i < 64; i++ {
w1[i] = w[i] ^ w[i+4]
}
a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
for j := 0; j < 64; j++ {
ss1 = sm3rotl(sm3rotl(a, 12)+e+sm3rotl(sm3t(j), uint32(j)), 7)
ss2 = ss1 ^ sm3rotl(a, 12)
tt1 = sm3ff(a, b, c, j) + d + ss2 + w1[j]
tt2 = sm3gg(e, f, g, j) + h + ss1 + w[j]
d = c
c = sm3rotl(b, 9)
b = a
a = tt1
h = g
g = sm3rotl(f, 19)
f = e
e = sm3p0(tt2)
}
h0 ^= a
h1 ^= b
h2 ^= c
h3 ^= d
h4 ^= e
h5 ^= f
h6 ^= g
h7 ^= h
p = p[chunk:]
}
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
}
func sm3t(j int) uint32 {
if j >= 16 {
return 0x7A879D8A
}
return 0x79CC4519
}
func sm3ff(x, y, z uint32, j int) uint32 {
if j >= 16 {
return ((x | y) & (x | z) & (y | z))
}
return x ^ y ^ z
}
func sm3gg(x, y, z uint32, j int) uint32 {
if j >= 16 {
return ((x & y) | ((^x) & z))
}
return x ^ y ^ z
}
func sm3rotl(x, n uint32) uint32 {
return (x << (n % 32)) | (x >> (32 - (n % 32)))
}
func sm3p0(x uint32) uint32 {
return x ^ sm3rotl(x, 9) ^ sm3rotl(x, 17)
}
func sm3p1(x uint32) uint32 {
return x ^ sm3rotl(x, 15) ^ sm3rotl(x, 23)
}

sm4:

block.go

package sm4
func (c *sm4Cipher) generateSubkeys(keyBytes []byte) {
var key = make([]uint32, 4)
var k = make([]uint32, 4)
key[0] = (uint32(keyBytes[0]) << 24) | (uint32(keyBytes[1]) << 16) | (uint32(keyBytes[2]) << 8) | (uint32(keyBytes[3]))
key[1] = (uint32(keyBytes[4]) << 24) | (uint32(keyBytes[5]) << 16) | (uint32(keyBytes[6]) << 8) | (uint32(keyBytes[7]))
key[2] = (uint32(keyBytes[8]) << 24) | (uint32(keyBytes[9]) << 16) | (uint32(keyBytes[10]) << 8) | (uint32(keyBytes[11]))
key[3] = (uint32(keyBytes[12]) << 24) | (uint32(keyBytes[13]) << 16) | (uint32(keyBytes[14]) << 8) | (uint32(keyBytes[15]))
k[0] = key[0] ^ sm4fk[0]
k[1] = key[1] ^ sm4fk[1]
k[2] = key[2] ^ sm4fk[2]
k[3] = key[3] ^ sm4fk[3]
for i := 0; i < 32; i++ {
c.subkeys[i] = k[0] ^ sm4kt(k[1]^k[2]^k[3]^sm4ck[i])
k[0] = k[1]
k[1] = k[2]
k[2] = k[3]
k[3] = c.subkeys[i]
}
}
func encryptBlock(subkeys []uint32, dst, src []byte) {
cryptBlock(subkeys, dst, src, false)
}
func decryptBlock(subkeys []uint32, dst, src []byte) {
cryptBlock(subkeys, dst, src, true)
}
func cryptBlock(subkeys []uint32, dst, src []byte, decrypt bool) {
var m = make([]uint32, 4)
var o = make([]uint32, 4)
m[0] = (uint32(src[0]) << 24) | (uint32(src[1]) << 16) | (uint32(src[2]) << 8) | (uint32(src[3]))
m[1] = (uint32(src[4]) << 24) | (uint32(src[5]) << 16) | (uint32(src[6]) << 8) | (uint32(src[7]))
m[2] = (uint32(src[8]) << 24) | (uint32(src[9]) << 16) | (uint32(src[10]) << 8) | (uint32(src[11]))
m[3] = (uint32(src[12]) << 24) | (uint32(src[13]) << 16) | (uint32(src[14]) << 8) | (uint32(src[15]))
if decrypt {
for j := 32; j > 0; j-- {
tmp := sm4f(m[0], m[1], m[2], m[3], subkeys[j-1])
m[0] = m[1]
m[1] = m[2]
m[2] = m[3]
m[3] = tmp
}
} else {
for j := 0; j < 32; j++ {
tmp := sm4f(m[0], m[1], m[2], m[3], subkeys[j])
m[0] = m[1]
m[1] = m[2]
m[2] = m[3]
m[3] = tmp
}
}
sm4r(o, m)
for j := 0; j < 4; j++ {
dst[j*4] = uint8((o[j] >> 24))
dst[j*4+1] = uint8((o[j] >> 16))
dst[j*4+2] = uint8((o[j] >> 8))
dst[j*4+3] = uint8((o[j]))
}
}
func sm4rotl(x uint32, i uint8) uint32 {
return (x << (i % 32)) | (x >> (32 - (i % 32)))
}
func sm4tao(a uint32) uint32 {
return sm4sbox[uint8(a)] | (sm4sbox[uint8(a>>8)] << 8) | (sm4sbox[uint8(a>>16)] << 16) | (sm4sbox[uint8(a>>24)] << 24)
}
func sm4l(b uint32) uint32 {
return b ^ sm4rotl(b, 2) ^ sm4rotl(b, 10) ^ sm4rotl(b, 18) ^ sm4rotl(b, 24)
}
func sm4t(x uint32) uint32 {
return sm4l(sm4tao(x))
}
func sm4f(x0, x1, x2, x3, rk uint32) uint32 {
return x0 ^ sm4t(x1^x2^x3^rk)
}
func sm4r(o, i []uint32) {
o[0] = i[3]
o[1] = i[2]
o[2] = i[1]
o[3] = i[0]
}
func sm4kl(b uint32) uint32 {
return b ^ sm4rotl(b, 13) ^ sm4rotl(b, 23)
}
func sm4kt(x uint32) uint32 {
return sm4kl(sm4tao(x))
}

cipher.go

package sm4
import (
"crypto/cipher"
"strconv"
)
//BlockSize The SM4 block size in bytes.
const BlockSize = 16
// KeySizeError key error
type KeySizeError int
func (k KeySizeError) Error() string {
return "sm4: invalid key size " + strconv.Itoa(int(k))
}
// sm4Cipher is an instance of SM4 encryption.
type sm4Cipher struct {
subkeys [32]uint32
}
// NewCipher creates and returns a new cipher.Block.
func NewCipher(key []byte) (cipher.Block, error) {
if len(key) != 16 {
return nil, KeySizeError(len(key))
}
c := new(sm4Cipher)
c.generateSubkeys(key)
return c, nil
}
func (c *sm4Cipher) BlockSize() int {
return BlockSize
}
func (c *sm4Cipher) Encrypt(dst, src []byte) {
encryptBlock(c.subkeys[:], dst, src)
}
func (c *sm4Cipher) Decrypt(dst, src []byte) {
decryptBlock(c.subkeys[:], dst, src)
}

const.go

package sm4
var sm4fk = [4]uint32{
0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc,
}
var sm4ck = [32]uint32{
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
}
var sm4sbox = [256]uint32{
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
}

 

使用方法

//sm3 sm4 加解密示例
hash := sm3.New()
hash.Write([]byte("123456"))
result := hash.Sum(nil)
println("sm3 hash = ", hex.EncodeToString(result))
a := []byte("123456")
key := []byte("abc.123")
decrypto := SM4Encrypt(a, key)
fmt.Println("sm4加密后:", hex.EncodeToString(decrypto))
i := SM4Decrypto(decrypto, key)
fmt.Println("sm4解密后:", string(i))

补充获取 sm3 hmac 方法

 

secret := []byte("abc.123")
message := []byte("123456")
hash := hmac.New(sm3.New, secret)
hash.Write(message)
// to lowercase hexits

fmt.Printf("sm3 hmac:%s\n", hex.EncodeToString(hash.Sum(nil)))

 

不想平凡,奈何太懒 T_T

推荐这些文章:

golang数组的简单应用

打印A-Z

package main

import "fmt"

func main() {

var arr01 [26]byte

for i := 0; i < len(arr01); i++ {
arr01[i] = 'A' + byte(i)
}
for i := 0; i < len(arr01); i++ {
fmt.Printf("%c ", arr01[i])
}
}

找出数组中的最大值以及它的下标

package main

import "fmt"

func main() {

var num [5]int = [5]int{...

golang生成验证码

//生成验证码
func randomKey2(length, level int) (strPol string) {
var slicePol []byte
var str string
switch level {
case 1:
str = "0123456789"
default:
str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
}
rand.Seed(time.Now().UnixNano())
for i := 0; i < length; i++ {
...

3、golang入门-基本数据类型

Go 语言按类别有以下几种数据类型:

序号
类型和描述

1
布尔型布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。

2
数字类型整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。

3
字符串类型:字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。

4
派生类型:包括:

(a) 指针类型(Pointer)
(b) 数组类型
(c) 结...

golang redis队列

package main

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/garyburd/redigo/redis"
"time"
)

type RedisPool struct {
pool *redis.Pool
}

func newRedisPool(server, password string) (*RedisPool, error) {

if server == "" {
server = ":6379"
}
...

golang: 学会几个语法上的新写法

看了VictoriaMetrics,学会了几个新写法,记录下来:
1. 数组拷贝
以前:
arr := make([]byte, 0, len(oldArr)
arr = append(arr, oldArr...)

现在:
arr := append([]byte{}, oldArr...)

2.interface{}类型断言
以前:
func converToMyType(interfaceType interface{}) *MyType{
var inst *MyType
var ok bool
inst,ok = interfaceType.(*MyTy...

golang map做排序后,md5加密

Go map字典排序后md5加密
 

package main

import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"sort"
"strings"
)

func main() {
params := make(map[string]interface{})
params["name"] = "test"
params["key"] = "123aa!31."
params["domain"] = "http...

golang map与string的相互转换

一.map转string

import (
"encoding/json"
)

func MapToJson(param map[string]interface{}) string{
dataType , _ := json.Marshal(param)
dataString := string(dataType)
return dataString
}

 
二.string转map

import (
"encoding/json"
)

func JsonToMap(str string) map[string]int...

golang编程总结(一)工作区,gopath,命令源码文件

工作区和gopath
gopath下面有src,pkg,bin三个目录,src存放源代码,pkg和bin用于install,build之后生成的二进制文件的存放
工作区就是gopath指示的目录
如何在命令源码文件中添加自定义的启动参数
//定义一个接受参数的变量
var name string
func init(){
flag.StringVar(&name,"name","every one","input you name")
}
func main(){
//解析命令行参数
flag.Parse()
fmt.printf("hello...

shiro加密底层

protected byte[] hash(byte[] bytes, byte[] salt, int hashIterations) throws UnknownAlgorithmException { MessageDigest digest = this.getDigest(this.getAlgorithmName()); if (salt != null) { digest.reset(); digest.update(salt); } byte[] hashed = digest.digest(bytes); int i...

golang中字符串、数值、2进制、8进制、16进制、10进制、日期和字符串之间的转换

package main

import (
"fmt"
"reflect"
"strconv"
"time"
)

func main() {
a := 15 // 整数转浮点数
b := float64(a) // go支持显示类型转换,以满足严格的类型要求
fmt.Println(b, reflect.TypeOf(b))

c := "123456" // 字符串转整数
d, _ := strconv.Atoi(c)
fmt.Printf("%d:%T\n",d,d)

var e string = "15.86" // 字符串转浮点数
f, _ :=...

文章标题:golang sm3、sm4 加密
文章链接:https://www.dianjilingqu.com/51177.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。
THE END
< <上一篇
下一篇>>