210 lines
4.3 KiB
Go
210 lines
4.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"math/big"
|
|
"strings"
|
|
"voucher/internal/pkg/cmbv2/model"
|
|
"voucher/internal/pkg/helper"
|
|
)
|
|
|
|
func GenerateSM4Key() []byte {
|
|
str := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
|
buffer := make([]byte, 16)
|
|
for i := 0; i < 16; i++ {
|
|
nextInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(str))))
|
|
buffer[i] = str[nextInt.Int64()]
|
|
}
|
|
return buffer
|
|
}
|
|
|
|
// GetSM4IV 获取SM4的IV
|
|
func GetSM4IV() []byte {
|
|
return RandomBytes(16)
|
|
}
|
|
|
|
func RandomBytes(length int) []byte {
|
|
str := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
|
buffer := make([]byte, length)
|
|
for i := 0; i < 16; i++ {
|
|
nextInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(str))))
|
|
buffer[i] = str[nextInt.Int64()]
|
|
}
|
|
return buffer
|
|
}
|
|
|
|
func Padding(input []byte, mode int) []byte {
|
|
if input == nil {
|
|
return nil
|
|
} else {
|
|
var ret []byte
|
|
if mode == 1 {
|
|
p := 16 - len(input)%16
|
|
ret = make([]byte, len(input)+p)
|
|
copy(ret, input)
|
|
|
|
for i := 0; i < p; i++ {
|
|
ret[len(input)+i] = byte(p)
|
|
}
|
|
} else {
|
|
p := input[len(input)-1]
|
|
ret = make([]byte, len(input)-int(p))
|
|
copy(ret, input[:len(input)-int(p)])
|
|
}
|
|
|
|
return ret
|
|
}
|
|
}
|
|
|
|
func AssemblingByteArray(key, iv []byte) []byte {
|
|
os := make([]byte, 0)
|
|
os = append(os, key...)
|
|
os = append(os, []byte("|")...)
|
|
os = append(os, iv...)
|
|
return os
|
|
}
|
|
|
|
func SortStructStr(req interface{}) string {
|
|
kvRows := helper.SortStructFieldsByKey(req)
|
|
|
|
var strToBeSigned strings.Builder
|
|
for _, kv := range kvRows {
|
|
if kv.Key == "sign" {
|
|
continue
|
|
}
|
|
if kv.Value == "" {
|
|
continue
|
|
}
|
|
strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
|
|
}
|
|
|
|
return strings.TrimRight(strToBeSigned.String(), "&")
|
|
}
|
|
|
|
func BigIntToByte(n *big.Int) []byte {
|
|
byteArray := n.Bytes()
|
|
|
|
// If the bytes is not a multiple of 32, pad with zero bytes.
|
|
byteArrLen := len(byteArray)
|
|
KeyBytes := 32
|
|
if byteArrLen == KeyBytes {
|
|
return byteArray
|
|
}
|
|
byteArray = append(make([]byte, KeyBytes-byteArrLen), byteArray...)
|
|
|
|
// If the most significant byte's most significant bit is set,
|
|
// prepend a 0 byte to the slice to avoid being interpreted as a negative number.
|
|
if (byteArray[0] & 0x80) != 0 {
|
|
byteArray = append([]byte{0}, byteArray...)
|
|
}
|
|
return byteArray
|
|
}
|
|
|
|
func JoinBytes(params ...[]byte) ([]byte, error) {
|
|
var buffer bytes.Buffer
|
|
for i := 0; i < len(params); i++ {
|
|
_, err := buffer.Write(params[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return buffer.Bytes(), nil
|
|
}
|
|
|
|
func HexToPrivateKey(params *Sm2P256Curve, d []byte) (*model.PrivateKey, error) {
|
|
k := new(big.Int).SetBytes(d)
|
|
|
|
c := NewP256Sm2()
|
|
|
|
//params := c.Params()
|
|
n := new(big.Int).Sub(params.N, model.One)
|
|
if k.Cmp(n) >= 0 {
|
|
return nil, fmt.Errorf("privateKey is overflow")
|
|
}
|
|
|
|
pri := &model.PrivateKey{
|
|
PublicKey: &model.PublicKey{},
|
|
D: nil,
|
|
}
|
|
|
|
pri.PublicKey.Curve = c
|
|
pri.D = k
|
|
pri.PublicKey.X, pri.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
|
|
|
|
return pri, nil
|
|
}
|
|
|
|
func HexToPublicKey(curve *Sm2P256Curve, d []byte) (*model.PublicKey, error) {
|
|
|
|
if len(d) == 65 && d[0] == byte(0x04) {
|
|
d = d[1:]
|
|
}
|
|
|
|
if len(d) != 64 {
|
|
return nil, fmt.Errorf("publicKey is not 64 bytes: %d", len(d))
|
|
}
|
|
|
|
pub := new(model.PublicKey)
|
|
|
|
pub.Curve = curve
|
|
|
|
pub.X = new(big.Int).SetBytes(d[:32])
|
|
pub.Y = new(big.Int).SetBytes(d[32:])
|
|
|
|
return pub, nil
|
|
}
|
|
|
|
func PrivateKeyToHex(key *model.PrivateKey) string {
|
|
return key.D.Text(16)
|
|
}
|
|
|
|
func PublicKeyToHex(key *model.PublicKey) string {
|
|
x := key.X.Bytes()
|
|
y := key.Y.Bytes()
|
|
if n := len(x); n < 32 {
|
|
x = append(zeroByteSlice()[:32-n], x...)
|
|
}
|
|
if n := len(y); n < 32 {
|
|
y = append(zeroByteSlice()[:32-n], y...)
|
|
}
|
|
var c []byte
|
|
c = append(c, x...)
|
|
c = append(c, y...)
|
|
c = append([]byte{0x04}, c...)
|
|
return hex.EncodeToString(c)
|
|
}
|
|
|
|
// 32byte
|
|
func zeroByteSlice() []byte {
|
|
return []byte{
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
}
|
|
}
|
|
|
|
func HexToSignature(hexStr string) (s model.Signature, err error) {
|
|
signData, err := hex.DecodeString(hexStr)
|
|
if err != nil {
|
|
return
|
|
}
|
|
rBy := make([]byte, 33)
|
|
copy(rBy[1:], signData[:32])
|
|
rBy[0] = 0x00
|
|
s.R = new(big.Int).SetBytes(rBy)
|
|
|
|
sBy := make([]byte, 33)
|
|
copy(sBy[1:], signData[32:64])
|
|
sBy[0] = 0x00
|
|
s.S = new(big.Int).SetBytes(sBy)
|
|
return
|
|
}
|