first push
This commit is contained in:
commit
39c1edf66a
|
@ -0,0 +1,30 @@
|
|||
package l_encrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/aes"
|
||||
)
|
||||
|
||||
func NewAES(app *AppEncrypt) ApiCrypt {
|
||||
return &AES{
|
||||
App: app,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *AES) Encrypt(data string) (encryptData []byte, err error) {
|
||||
|
||||
encrypt, err := aes.Encrypt(r.App.UniKEY, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("加密失败")
|
||||
}
|
||||
|
||||
return []byte(encrypt), nil
|
||||
}
|
||||
|
||||
func (r *AES) Decrypt(encryptData string) (decryptData []byte, err error) {
|
||||
decrypt, err := aes.Decrypt(r.App.UniKEY, encryptData)
|
||||
if err != nil || decrypt == "" {
|
||||
return nil, fmt.Errorf("解密失败")
|
||||
}
|
||||
return []byte(decrypt), nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package l_encrypt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAes(t *testing.T) {
|
||||
text := "YOUR NEEDD ENCRYPT TEXT"
|
||||
var appInfo = &AppEncrypt{
|
||||
UniKEY: "yourEncryptToken",
|
||||
}
|
||||
cryptFunc := Crypt(CryptAES)
|
||||
encryptData, err := cryptFunc(appInfo).Encrypt(text)
|
||||
t.Log(string(encryptData), err)
|
||||
decryptData, err := cryptFunc(appInfo).Decrypt(string(encryptData))
|
||||
t.Log(string(decryptData), err)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package l_encrypt
|
||||
|
||||
const (
|
||||
NO_CRYPT cryptType = iota + 1
|
||||
CryptRSA
|
||||
CryptSM2
|
||||
CryptSM4
|
||||
CryptAES
|
||||
)
|
||||
|
||||
type cryptType int32
|
|
@ -0,0 +1,90 @@
|
|||
package aes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// PKCS7Padding pads an input slice to be a multiple of the block size.
|
||||
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(ciphertext)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(ciphertext, padtext...)
|
||||
}
|
||||
|
||||
// PKCS7UnPadding removes the padding from a padded ciphertext.
|
||||
func PKCS7UnPadding(origData []byte) ([]byte, error) {
|
||||
length := len(origData)
|
||||
unpadding := int(origData[length-1])
|
||||
if unpadding > length {
|
||||
return nil, fmt.Errorf("unpadding size is invalid")
|
||||
}
|
||||
return origData[:(length - unpadding)], nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts a string to an encrypted string.
|
||||
func Encrypt(key, text string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b := base64.StdEncoding.EncodeToString([]byte(text))
|
||||
ciphertext := make([]byte, aes.BlockSize+len(b))
|
||||
iv := ciphertext[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
|
||||
ciphertext = PKCS7Padding(ciphertext, aes.BlockSize)
|
||||
|
||||
return base64.StdEncoding.EncodeToString(ciphertext), nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts an encrypted string to an original string.
|
||||
func Decrypt(key, cryptoText string) (string, error) {
|
||||
ciphertext, _ := base64.StdEncoding.DecodeString(cryptoText)
|
||||
ciphertext, err := PKCS7UnPadding(ciphertext)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(ciphertext) < aes.BlockSize {
|
||||
return "", fmt.Errorf("ciphertext too short")
|
||||
}
|
||||
iv := ciphertext[:aes.BlockSize]
|
||||
ciphertext = ciphertext[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(ciphertext, ciphertext)
|
||||
|
||||
result, err := base64.StdEncoding.DecodeString(string(ciphertext))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(result), nil
|
||||
}
|
||||
|
||||
// EncryptType encrypts a type to an encrypted string.
|
||||
// Note: This assumes the type can be marshaled to JSON.
|
||||
func EncryptType(key string, data interface{}) (string, error) {
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return Encrypt(key, string(jsonData))
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package rsa
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// parseRSAPublicKeyFromPEM 解析PEM编码的RSA公钥
|
||||
func parseRSAPublicKeyFromPEM(pemData []byte) (*rsa.PublicKey, error) {
|
||||
block, _ := pem.Decode(pemData)
|
||||
if block == nil || block.Type != "PUBLIC KEY" {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the RSA public key")
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return pub, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown public key type in PKIX wrapping")
|
||||
}
|
||||
}
|
||||
|
||||
// encrypt 使用RSA公钥加密数据
|
||||
func Encrypt(publicKeyPEM string, plaintext string) ([]byte, error) {
|
||||
var encryptedData []byte
|
||||
// 将PEM编码的公钥转换为[]byte
|
||||
pemData := []byte(publicKeyPEM)
|
||||
|
||||
// 解析PEM数据以获取公钥
|
||||
pubKey, err := parseRSAPublicKeyFromPEM(pemData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := sha256.New()
|
||||
maxBlockSize := pubKey.Size() - 2*hash.Size() - 2
|
||||
// 创建用于加密的随机填充
|
||||
label := []byte("") // OAEP标签,对于某些情况可能是非空的
|
||||
for len(plaintext) > 0 {
|
||||
blockSize := maxBlockSize
|
||||
if len(plaintext) < maxBlockSize {
|
||||
blockSize = len(plaintext)
|
||||
}
|
||||
block := plaintext[:blockSize]
|
||||
encryptedBlock, err := rsa.EncryptOAEP(hash, rand.Reader, pubKey, []byte(block), label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encryptedData = append(encryptedData, encryptedBlock...)
|
||||
plaintext = plaintext[blockSize:]
|
||||
}
|
||||
return encryptedData, nil
|
||||
}
|
||||
|
||||
// parseRSAPrivateKeyFromPEM 解析PEM编码的RSA私钥
|
||||
func parseRSAPrivateKeyFromPEM(pemData []byte) (*rsa.PrivateKey, error) {
|
||||
block, _ := pem.Decode(pemData)
|
||||
if block == nil || block.Type != "RSA PRIVATE KEY" {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the RSA private key")
|
||||
}
|
||||
|
||||
// 尝试使用PKCS#1 v1.5
|
||||
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
// 如果失败,尝试使用PKCS#8
|
||||
privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch k := privInterface.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
priv = k
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown private key type in PKCS#8 wrapping")
|
||||
}
|
||||
}
|
||||
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
// decrypt 使用RSA私钥解密数据
|
||||
func Decrypt(privateKeyPEM string, encryptedDataBase64 string) ([]byte, error) {
|
||||
var decryptedData []byte
|
||||
// 将PEM编码的私钥转换为[]byte
|
||||
pemData := []byte(privateKeyPEM)
|
||||
// 解析PEM数据以获取私钥
|
||||
privKey, err := parseRSAPrivateKeyFromPEM(pemData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keySize := privKey.PublicKey.Size()
|
||||
label := []byte("") // OAEP标签,对于某些情况可能是非空的
|
||||
hash := sha256.New()
|
||||
// 将Base64编码的加密数据解码为字节切片
|
||||
encryptedData, err := base64.StdEncoding.DecodeString(encryptedDataBase64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for len(encryptedData) > 0 {
|
||||
block := encryptedData[:keySize]
|
||||
// 这里假设使用的是OAEP填充和SHA-256哈希函数
|
||||
decryptedBlock, err := rsa.DecryptOAEP(hash, rand.Reader, privKey, block, label)
|
||||
if err != nil {
|
||||
//// 如果失败,可以尝试使用PKCS#1 v1.5填充
|
||||
decryptedBlock, err = rsa.DecryptPKCS1v15(rand.Reader, privKey, encryptedData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
decryptedData = append(decryptedData, decryptedBlock...)
|
||||
encryptedData = encryptedData[keySize:]
|
||||
}
|
||||
return decryptedData, nil
|
||||
}
|
||||
|
||||
// 生成密钥对
|
||||
func GenerateKey() (string, string, error) {
|
||||
// 生成私钥
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
// 导出私钥PKCS#1格式
|
||||
privKey := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
// 将私钥转换为PEM编码
|
||||
var privBlock = &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: privKey,
|
||||
}
|
||||
privPem := pem.EncodeToMemory(privBlock)
|
||||
// 导出公钥
|
||||
pubKey := &privateKey.PublicKey
|
||||
derPkix, err := x509.MarshalPKIXPublicKey(pubKey)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
// 将公钥转换为PEM编码
|
||||
var pubBlock = &pem.Block{
|
||||
Type: "PUBLIC KEY",
|
||||
Bytes: derPkix,
|
||||
}
|
||||
pubPem := pem.EncodeToMemory(pubBlock)
|
||||
pri := strings.Replace(string(privPem), "-----BEGIN RSA PRIVATE KEY-----\n", "", -1)
|
||||
pri = strings.Replace(pri, "\n-----END RSA PRIVATE KEY-----\n", "", -1)
|
||||
pri = strings.Replace(pri, "\n", "", -1)
|
||||
pub := strings.Replace(string(pubPem), "-----BEGIN PUBLIC KEY-----\n", "", -1)
|
||||
pub = strings.Replace(pub, "\n-----END PUBLIC KEY-----\n", "", -1)
|
||||
pub = strings.Replace(pub, "\n", "", -1)
|
||||
return pub, pri, nil
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package sm2
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/tjfoc/gmsm/sm2"
|
||||
"math/big"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 生成公钥、私钥
|
||||
func GenerateSM2Key() (PublicKey string, PrivateKey string, err error) {
|
||||
// 生成私钥、公钥
|
||||
privKey, err := sm2.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
|
||||
return "", "", err
|
||||
}
|
||||
return PublicKeyToString(&privKey.PublicKey), PrivateKeyToString(privKey), nil
|
||||
}
|
||||
|
||||
// GenerateKey 生成密钥对
|
||||
func GenerateKey() (string, string) {
|
||||
pri, _ := sm2.GenerateKey(rand.Reader)
|
||||
hexPri := pri.D.Text(16)
|
||||
// 获取公钥
|
||||
publicKeyHex := PublicKeyToString(&pri.PublicKey)
|
||||
return strings.ToUpper(hexPri), publicKeyHex
|
||||
}
|
||||
|
||||
// PublicKeyToString 公钥sm2.PublicKey转字符串(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
|
||||
func PublicKeyToString(publicKey *sm2.PublicKey) string {
|
||||
xBytes := publicKey.X.Bytes()
|
||||
yBytes := publicKey.Y.Bytes()
|
||||
|
||||
// 确保坐标字节切片长度相同
|
||||
byteLen := len(xBytes)
|
||||
if len(yBytes) > byteLen {
|
||||
byteLen = len(yBytes)
|
||||
}
|
||||
|
||||
// 为坐标补齐前导零
|
||||
xBytes = append(make([]byte, byteLen-len(xBytes)), xBytes...)
|
||||
yBytes = append(make([]byte, byteLen-len(yBytes)), yBytes...)
|
||||
|
||||
// 添加 "04" 前缀
|
||||
publicKeyBytes := append([]byte{0x04}, append(xBytes, yBytes...)...)
|
||||
|
||||
return strings.ToUpper(hex.EncodeToString(publicKeyBytes))
|
||||
}
|
||||
|
||||
// PrivateKeyToString 私钥sm2.PrivateKey 转字符串(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
|
||||
func PrivateKeyToString(privateKey *sm2.PrivateKey) string {
|
||||
return strings.ToUpper(hex.EncodeToString(privateKey.D.Bytes()))
|
||||
}
|
||||
|
||||
func SM2Decrypt(cipherText, publicKey string, privateKey string) (string, error) {
|
||||
if cipherText == "" {
|
||||
return "", nil
|
||||
}
|
||||
decodedBytes, err := base64.StdEncoding.DecodeString(cipherText)
|
||||
if err != nil {
|
||||
|
||||
return "", nil
|
||||
}
|
||||
decrypt, err := decryptLoc(publicKey, privateKey, string(decodedBytes))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return decrypt, nil
|
||||
}
|
||||
|
||||
func SM2Encrypt(cipherText string, privateKey string) (string, error) {
|
||||
if cipherText == "" {
|
||||
return "", nil
|
||||
}
|
||||
decrypt, err := encryptLoc(privateKey, cipherText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return decrypt, nil
|
||||
}
|
||||
|
||||
func encryptLoc(publicKeyStr, data string) (string, error) {
|
||||
publicKeyObj, err := StringToPublicKey(publicKeyStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
decrypt, err := sm2.Encrypt(publicKeyObj, []byte(data), rand.Reader, sm2.C1C2C3)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resultStr := hex.EncodeToString(decrypt)
|
||||
return base64.StdEncoding.EncodeToString([]byte(resultStr)), nil
|
||||
}
|
||||
|
||||
func decryptLoc(publicKeyStr, privateKeyStr, cipherText string) (string, error) {
|
||||
publicKeyObj, err := StringToPublicKey(publicKeyStr)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
privateKeyObj, err := StringToPrivateKey(privateKeyStr, publicKeyObj)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
decodeString, err := hex.DecodeString(cipherText)
|
||||
decrypt, err := sm2.Decrypt(privateKeyObj, decodeString, sm2.C1C2C3)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
resultStr := string(decrypt)
|
||||
return resultStr, nil
|
||||
}
|
||||
|
||||
// StringToPrivateKey 私钥还原为 sm2.PrivateKey对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
|
||||
func StringToPrivateKey(privateKeyStr string, publicKey *sm2.PublicKey) (*sm2.PrivateKey, error) {
|
||||
privateKeyBytes, err := hex.DecodeString(privateKeyStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将字节切片转换为大整数
|
||||
d := new(big.Int).SetBytes(privateKeyBytes)
|
||||
|
||||
// 创建 sm2.PrivateKey 对象
|
||||
privateKey := &sm2.PrivateKey{
|
||||
PublicKey: *publicKey,
|
||||
D: d,
|
||||
}
|
||||
|
||||
return privateKey, nil
|
||||
}
|
||||
|
||||
// StringToPublicKey 公钥字符串还原为 sm2.PublicKey 对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
|
||||
func StringToPublicKey(publicKeyStr string) (*sm2.PublicKey, error) {
|
||||
publicKeyBytes, err := hex.DecodeString(publicKeyStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 提取 x 和 y 坐标字节切片
|
||||
curve := sm2.P256Sm2().Params()
|
||||
byteLen := (curve.BitSize + 7) / 8
|
||||
xBytes := publicKeyBytes[1 : byteLen+1]
|
||||
yBytes := publicKeyBytes[byteLen+1 : 2*byteLen+1]
|
||||
|
||||
// 将字节切片转换为大整数
|
||||
x := new(big.Int).SetBytes(xBytes)
|
||||
y := new(big.Int).SetBytes(yBytes)
|
||||
|
||||
// 创建 sm2.PublicKey 对象
|
||||
publicKey := &sm2.PublicKey{
|
||||
Curve: curve,
|
||||
X: x,
|
||||
Y: y,
|
||||
}
|
||||
|
||||
return publicKey, nil
|
||||
}
|
||||
|
||||
// 验证签名
|
||||
func VerSm2Sig(pub *sm2.PublicKey, msg []byte, sign []byte) bool {
|
||||
isok := pub.Verify(msg, sign)
|
||||
return isok
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package sm2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
SELF_PRI = "47388B05A25F7EF05C6B663583AEB2F8C0CB87A4E77F3AB55B58AC51E60CDB31"
|
||||
|
||||
SELF_PUB = "0475904CB1A2F66077E964174995B319B0F1FA1DC593D57D5E7351B5E56F4E4E2E114D9A4234F66D799055566231170467EDA908E124D91FF826589A7CCE7450DA"
|
||||
)
|
||||
|
||||
func TestGenerateSM2KeyPair(t *testing.T) {
|
||||
// Generate a new SM2 key pair
|
||||
privateKey, publicKey := GenerateKey()
|
||||
|
||||
// Print the private and public keys
|
||||
fmt.Printf("Private Key: %s\n", privateKey)
|
||||
fmt.Printf("Public Key: %s\n", publicKey)
|
||||
|
||||
data := "{\"name\":\"张三\",\"sex\":1,\"is_human\":true}"
|
||||
en, err := SM2Encrypt(data, publicKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
decrypt, err := SM2Decrypt(en, publicKey, privateKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Log(decrypt)
|
||||
|
||||
}
|
||||
|
||||
func TestSM2Encrypt(t *testing.T) {
|
||||
t.Log(encrypt())
|
||||
}
|
||||
|
||||
func TestSM2Decrypt(t *testing.T) {
|
||||
en := "MDRmNGM0YTEyMGZlNjZhZDAyNTZhYjQ1MDQyOGM0MmIzMDA1MmIwN2NkNzExYjI2YWM1Mjg1MTMzOWU1NmNjNWIzYTRkMThhZWU4N2VjNmRiMTc5OTExOGVlYzg0YzQ5ZDY0N2EyZDVmMTY3ZTBiZmU3MTAxMDMzNjFlYjgwNGQ1NWU3Mjg3YjlmZDk2OTIwMzRhMWQ4NmNkMGRlNTI0ODE0NDAxNjJjMGMzNmExYmY4YjdlZDJlM2E5OWY3ZjQ3MjI4NWMxZTZkNTc4NWI0ZTgyNWNiNGU2"
|
||||
decrypt, err := SM2Decrypt(en, SELF_PUB, SELF_PRI)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Log(decrypt)
|
||||
}
|
||||
|
||||
func encrypt() string {
|
||||
data := "{\n \"pcode\": \"110000000000\",\n \"page\": 1,\n \"limit\": 10\n}"
|
||||
en, err := SM2Encrypt(data, SELF_PUB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return en
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,219 @@
|
|||
package sm2
|
||||
|
||||
// reference to ecdsa
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"github.com/tjfoc/gmsm/sm3"
|
||||
"io"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var (
|
||||
default_uid = []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}
|
||||
)
|
||||
|
||||
type PublicKey struct {
|
||||
elliptic.Curve
|
||||
X, Y *big.Int
|
||||
}
|
||||
|
||||
type PrivateKey struct {
|
||||
PublicKey
|
||||
D *big.Int
|
||||
}
|
||||
|
||||
type sm2Signature struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
func (priv *PrivateKey) Public() crypto.PublicKey {
|
||||
return &priv.PublicKey
|
||||
}
|
||||
|
||||
var errZeroParam = errors.New("zero parameter")
|
||||
var one = new(big.Int).SetInt64(1)
|
||||
var two = new(big.Int).SetInt64(2)
|
||||
|
||||
func (priv *PrivateKey) Sign(random io.Reader, msg []byte, signer crypto.SignerOpts) ([]byte, error) {
|
||||
r, s, err := Sm2Sign(priv, msg, nil, random)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return asn1.Marshal(sm2Signature{r, s})
|
||||
}
|
||||
|
||||
func Sm2Sign(priv *PrivateKey, msg, uid []byte, random io.Reader) (r, s *big.Int, err error) {
|
||||
digest, err := priv.PublicKey.Sm3Digest(msg, uid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
e := new(big.Int).SetBytes(digest)
|
||||
c := priv.PublicKey.Curve
|
||||
N := c.Params().N
|
||||
if N.Sign() == 0 {
|
||||
return nil, nil, errZeroParam
|
||||
}
|
||||
var k *big.Int
|
||||
for { // 调整算法细节以实现SM2
|
||||
for {
|
||||
k, err = randFieldElement(c, random)
|
||||
if err != nil {
|
||||
r = nil
|
||||
return
|
||||
}
|
||||
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
|
||||
r.Add(r, e)
|
||||
r.Mod(r, N)
|
||||
if r.Sign() != 0 {
|
||||
if t := new(big.Int).Add(r, k); t.Cmp(N) != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
rD := new(big.Int).Mul(priv.D, r)
|
||||
s = new(big.Int).Sub(k, rD)
|
||||
d1 := new(big.Int).Add(priv.D, one)
|
||||
d1Inv := new(big.Int).ModInverse(d1, N)
|
||||
s.Mul(s, d1Inv)
|
||||
s.Mod(s, N)
|
||||
if s.Sign() != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (pub *PublicKey) Sm3Digest(msg, uid []byte) ([]byte, error) {
|
||||
if len(uid) == 0 {
|
||||
uid = default_uid
|
||||
}
|
||||
|
||||
za, err := getZ(pub, uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e, err := msgHash(za, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return e.Bytes(), nil
|
||||
}
|
||||
|
||||
func Sm2Verify(pub *PublicKey, msg, uid []byte, r, s *big.Int) bool {
|
||||
c := pub.Curve
|
||||
N := c.Params().N
|
||||
one := new(big.Int).SetInt64(1)
|
||||
if r.Cmp(one) < 0 || s.Cmp(one) < 0 {
|
||||
return false
|
||||
}
|
||||
if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
|
||||
return false
|
||||
}
|
||||
if len(uid) == 0 {
|
||||
uid = default_uid
|
||||
}
|
||||
za, err := getZ(pub, uid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
e, err := msgHash(za, msg)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
t := new(big.Int).Add(r, s)
|
||||
t.Mod(t, N)
|
||||
if t.Sign() == 0 {
|
||||
return false
|
||||
}
|
||||
var x *big.Int
|
||||
x1, y1 := c.ScalarBaseMult(s.Bytes())
|
||||
x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
|
||||
x, _ = c.Add(x1, y1, x2, y2)
|
||||
|
||||
x.Add(x, e)
|
||||
x.Mod(x, N)
|
||||
return x.Cmp(r) == 0
|
||||
}
|
||||
|
||||
func msgHash(za, msg []byte) (*big.Int, error) {
|
||||
e := sm3.New()
|
||||
e.Write(za)
|
||||
e.Write(msg)
|
||||
return new(big.Int).SetBytes(e.Sum(nil)[:32]), nil
|
||||
}
|
||||
|
||||
func bigIntToByte(n *big.Int) []byte {
|
||||
byteArray := n.Bytes()
|
||||
// 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 getZ(pub *PublicKey, uid []byte) ([]byte, error) {
|
||||
z := sm3.New()
|
||||
uidLen := len(uid) * 8
|
||||
entla := []byte{byte(uidLen >> 8), byte(uidLen & 255)}
|
||||
z.Write(entla)
|
||||
z.Write(uid)
|
||||
|
||||
// a 先写死,原来的没有暴露
|
||||
z.Write(bigIntToByte(sm2P256ToBig(&sm2P256.a)))
|
||||
z.Write(bigIntToByte(sm2P256.B))
|
||||
z.Write(bigIntToByte(sm2P256.Gx))
|
||||
z.Write(bigIntToByte(sm2P256.Gy))
|
||||
|
||||
z.Write(bigIntToByte(pub.X))
|
||||
z.Write(bigIntToByte(pub.Y))
|
||||
return z.Sum(nil), nil
|
||||
}
|
||||
|
||||
func randFieldElement(c elliptic.Curve, random io.Reader) (k *big.Int, err error) {
|
||||
if random == nil {
|
||||
random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it.
|
||||
}
|
||||
params := c.Params()
|
||||
b := make([]byte, params.BitSize/8+8)
|
||||
_, err = io.ReadFull(random, b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
k = new(big.Int).SetBytes(b)
|
||||
n := new(big.Int).Sub(params.N, one)
|
||||
k.Mod(k, n)
|
||||
k.Add(k, one)
|
||||
return
|
||||
}
|
||||
|
||||
func GenerateKey(random io.Reader) (*PrivateKey, error) {
|
||||
c := P256Sm2()
|
||||
if random == nil {
|
||||
random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it.
|
||||
}
|
||||
params := c.Params()
|
||||
b := make([]byte, params.BitSize/8+8)
|
||||
_, err := io.ReadFull(random, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := new(big.Int).SetBytes(b)
|
||||
n := new(big.Int).Sub(params.N, two)
|
||||
k.Mod(k, n)
|
||||
k.Add(k, one)
|
||||
priv := new(PrivateKey)
|
||||
priv.PublicKey.Curve = c
|
||||
priv.D = k
|
||||
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
|
||||
|
||||
return priv, nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package sm2
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func ReadPrivateKeyFromHex(Dhex string) (*PrivateKey, error) {
|
||||
c := P256Sm2()
|
||||
d, err := hex.DecodeString(Dhex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k := new(big.Int).SetBytes(d)
|
||||
params := c.Params()
|
||||
one := new(big.Int).SetInt64(1)
|
||||
n := new(big.Int).Sub(params.N, one)
|
||||
if k.Cmp(n) >= 0 {
|
||||
return nil, errors.New("privateKey's D is overflow.")
|
||||
}
|
||||
priv := new(PrivateKey)
|
||||
priv.PublicKey.Curve = c
|
||||
priv.D = k
|
||||
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
func ReadPublicKeyFromHex(Qhex string) (*PublicKey, error) {
|
||||
q, err := hex.DecodeString(Qhex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(q) == 65 && q[0] == byte(0x04) {
|
||||
q = q[1:]
|
||||
}
|
||||
if len(q) != 64 {
|
||||
return nil, errors.New("publicKey is not uncompressed.")
|
||||
}
|
||||
pub := new(PublicKey)
|
||||
pub.Curve = P256Sm2()
|
||||
pub.X = new(big.Int).SetBytes(q[:32])
|
||||
pub.Y = new(big.Int).SetBytes(q[32:])
|
||||
return pub, nil
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/sm4/internal/sm2"
|
||||
zzsm2 "github.com/ZZMarquis/gm/sm2"
|
||||
"github.com/tjfoc/gmsm/sm3"
|
||||
"github.com/tjfoc/gmsm/x509"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func Sm2Decrypt(privateKey *sm2.PrivateKey, encryptData []byte) ([]byte, error) {
|
||||
C1Byte := make([]byte, 65)
|
||||
copy(C1Byte, encryptData[:65])
|
||||
x, y := elliptic.Unmarshal(privateKey.Curve, C1Byte)
|
||||
dBC1X, dBC1Y := privateKey.Curve.ScalarMult(x, y, bigIntToByte(privateKey.D))
|
||||
dBC1Bytes := elliptic.Marshal(privateKey.Curve, dBC1X, dBC1Y)
|
||||
|
||||
kLen := len(encryptData) - 65 - 32
|
||||
t, err := kdf(dBC1Bytes, kLen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
M := make([]byte, kLen)
|
||||
for i := 0; i < kLen; i++ {
|
||||
M[i] = encryptData[65+i] ^ t[i]
|
||||
}
|
||||
|
||||
C3 := make([]byte, 32)
|
||||
copy(C3, encryptData[len(encryptData)-32:])
|
||||
u := calculateHash(dBC1X, M, dBC1Y)
|
||||
|
||||
if bytes.Compare(u, C3) == 0 {
|
||||
return M, nil
|
||||
} else {
|
||||
return nil, errors.New("解密失败")
|
||||
}
|
||||
}
|
||||
|
||||
func Sm2Encrypt(publicKey *sm2.PublicKey, m []byte) ([]byte, error) {
|
||||
kLen := len(m)
|
||||
var C1, t []byte
|
||||
var err error
|
||||
var kx, ky *big.Int
|
||||
for {
|
||||
k, _ := rand.Int(rand.Reader, publicKey.Params().N)
|
||||
C1x, C1y := zzsm2.GetSm2P256V1().ScalarBaseMult(bigIntToByte(k))
|
||||
// C1x, C1y := sm2.P256Sm2().ScalarBaseMult(bigIntToByte(k))
|
||||
C1 = elliptic.Marshal(publicKey.Curve, C1x, C1y)
|
||||
|
||||
kx, ky = publicKey.ScalarMult(publicKey.X, publicKey.Y, bigIntToByte(k))
|
||||
kpbBytes := elliptic.Marshal(publicKey, kx, ky)
|
||||
t, err = kdf(kpbBytes, kLen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isAllZero(t) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
C2 := make([]byte, kLen)
|
||||
for i := 0; i < kLen; i++ {
|
||||
C2[i] = m[i] ^ t[i]
|
||||
}
|
||||
|
||||
C3 := calculateHash(kx, m, ky)
|
||||
|
||||
r := make([]byte, 0, len(C1)+len(C2)+len(C3))
|
||||
r = append(r, C1...)
|
||||
r = append(r, C2...)
|
||||
r = append(r, C3...)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func isAllZero(m []byte) bool {
|
||||
for i := 0; i < len(m); i++ {
|
||||
if m[i] != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func calculateHash(x *big.Int, M []byte, y *big.Int) []byte {
|
||||
digest := sm3.New()
|
||||
digest.Write(bigIntToByte(x))
|
||||
digest.Write(M)
|
||||
digest.Write(bigIntToByte(y))
|
||||
result := digest.Sum(nil)[:32]
|
||||
return result
|
||||
}
|
||||
|
||||
func bigIntToByte(n *big.Int) []byte {
|
||||
byteArray := n.Bytes()
|
||||
// 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 kdf(Z []byte, klen int) ([]byte, error) {
|
||||
ct := 1
|
||||
end := (klen + 31) / 32
|
||||
result := make([]byte, 0)
|
||||
for i := 1; i <= end; i++ {
|
||||
b, err := sm3hash(Z, toByteArray(ct))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, b...)
|
||||
ct++
|
||||
}
|
||||
last, err := sm3hash(Z, toByteArray(ct))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if klen%32 == 0 {
|
||||
result = append(result, last...)
|
||||
} else {
|
||||
result = append(result, last[:klen%32]...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func sm3hash(sources ...[]byte) ([]byte, error) {
|
||||
b, err := joinBytes(sources...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
md := make([]byte, 32)
|
||||
h := x509.SM3.New()
|
||||
h.Write(b)
|
||||
h.Sum(md[:0])
|
||||
return md, nil
|
||||
}
|
||||
|
||||
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 toByteArray(i int) []byte {
|
||||
byteArray := []byte{
|
||||
byte(i >> 24),
|
||||
byte((i & 16777215) >> 16),
|
||||
byte((i & 65535) >> 8),
|
||||
byte(i & 255),
|
||||
}
|
||||
return byteArray
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func GenAccessToken(token string) string {
|
||||
if token != "" {
|
||||
return token
|
||||
}
|
||||
now := time.Now()
|
||||
return strings.ToUpper(Md5Hash(now.Format("2006A01B02CD15E04F05"), ""))
|
||||
}
|
||||
|
||||
func Md5Hash(password, salt string) string {
|
||||
m := md5.New()
|
||||
m.Write([]byte(salt + password))
|
||||
return hex.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
|
||||
// GetSM4IV 获取SM4的IV
|
||||
func GetSM4IV() []byte {
|
||||
return []byte("UISwD9fW6cFh9SNS")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package sm4
|
||||
|
||||
import (
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/sm4/internal/sm2"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/sm4/internal/util"
|
||||
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ZZMarquis/gm/sm4"
|
||||
"math/big"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func checkInData(reqData map[string]string, key string) (string, error) {
|
||||
data, ok := reqData[key]
|
||||
if !ok {
|
||||
return "", errors.New("请求数据中不存在" + key)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func Sm4Decrypt(merchantId, privateKey, sopPublicKey, respJson string, isRequest bool) (string, error) {
|
||||
var reqData map[string]string
|
||||
err := json.Unmarshal([]byte(respJson), &reqData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
keys := [4]string{}
|
||||
if isRequest {
|
||||
keys = [4]string{"request", "signature", "encryptKey", "accessToken"}
|
||||
} else {
|
||||
keys = [4]string{"response", "signature", "encryptKey", "accessToken"}
|
||||
}
|
||||
var inEncryptKey, inAccessToken, inData, inSignature string
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
data, err := checkInData(reqData, keys[i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch keys[i] {
|
||||
case "request", "response":
|
||||
inData = data
|
||||
case "signature":
|
||||
inSignature = data
|
||||
case "encryptKey":
|
||||
inEncryptKey = data
|
||||
case "accessToken":
|
||||
inAccessToken = data
|
||||
}
|
||||
}
|
||||
|
||||
checked := verify(fmt.Sprintf("%s%s%s", inData, inEncryptKey, inAccessToken), inSignature, sopPublicKey, merchantId)
|
||||
if !checked {
|
||||
return "", errors.New("签名验证失败")
|
||||
}
|
||||
|
||||
priKey, err := sm2.ReadPrivateKeyFromHex(privateKey)
|
||||
if err != nil {
|
||||
return "", errors.New("读取私钥失败")
|
||||
}
|
||||
hexEncryptKey, err := hex.DecodeString(inEncryptKey)
|
||||
if err != nil {
|
||||
return "", errors.New("解密sm4key失败")
|
||||
}
|
||||
sm4Key, err := util.Sm2Decrypt(priKey, hexEncryptKey)
|
||||
|
||||
request, _ := base64.StdEncoding.DecodeString(inData)
|
||||
|
||||
encryptedSm4Key, err := sm4.CBCDecrypt(sm4Key, util.GetSM4IV(), request)
|
||||
|
||||
return string(util.Padding(encryptedSm4Key, 0)), nil
|
||||
}
|
||||
|
||||
func Sm4Encrypt(merchantId, privateKey, sopPublicKey, inputJson, token string, isRequest bool) (string, error) {
|
||||
sm4Key := util.GenerateSM4Key()
|
||||
iv := util.GetSM4IV()
|
||||
tmp, err := sm4.CBCEncrypt(sm4Key, iv, util.Padding([]byte(inputJson), 1))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
responseMsg := base64.StdEncoding.EncodeToString(tmp)
|
||||
responseMsg = addNewline(responseMsg)
|
||||
|
||||
pubKey, err := sm2.ReadPublicKeyFromHex(sopPublicKey)
|
||||
if err != nil {
|
||||
return "", errors.New("读取私钥失败")
|
||||
}
|
||||
encryptKeyBytes, err := util.Sm2Encrypt(pubKey, sm4Key)
|
||||
encryptKey := strings.ToUpper(hex.EncodeToString(encryptKeyBytes))
|
||||
|
||||
accessToken := util.GenAccessToken(token)
|
||||
signContent := fmt.Sprintf("%s%s%s", responseMsg, encryptKey, accessToken)
|
||||
signature, err := sign(merchantId, privateKey, signContent)
|
||||
|
||||
var reqData map[string]string
|
||||
|
||||
if isRequest {
|
||||
reqData = map[string]string{
|
||||
"request": responseMsg,
|
||||
"signature": signature,
|
||||
"encryptKey": encryptKey,
|
||||
"accessToken": accessToken,
|
||||
}
|
||||
} else {
|
||||
reqData = map[string]string{
|
||||
"response": responseMsg,
|
||||
"signature": signature,
|
||||
"encryptKey": encryptKey,
|
||||
"accessToken": accessToken,
|
||||
}
|
||||
}
|
||||
|
||||
jsonStr, err := json.Marshal(reqData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(jsonStr), err
|
||||
}
|
||||
|
||||
// GenerateKey 生成密钥对
|
||||
func GenerateKey() (string, string) {
|
||||
pri, _ := sm2.GenerateKey(rand.Reader)
|
||||
hexPri := pri.D.Text(16)
|
||||
// 获取公钥
|
||||
publicKeyHex := publicKeyToString(&pri.PublicKey)
|
||||
return strings.ToUpper(hexPri), publicKeyHex
|
||||
}
|
||||
|
||||
// publicKeyToString 公钥sm2.PublicKey转字符串(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
|
||||
func publicKeyToString(publicKey *sm2.PublicKey) string {
|
||||
xBytes := publicKey.X.Bytes()
|
||||
yBytes := publicKey.Y.Bytes()
|
||||
|
||||
// 确保坐标字节切片长度相同
|
||||
byteLen := len(xBytes)
|
||||
if len(yBytes) > byteLen {
|
||||
byteLen = len(yBytes)
|
||||
}
|
||||
|
||||
// 为坐标补齐前导零
|
||||
xBytes = append(make([]byte, byteLen-len(xBytes)), xBytes...)
|
||||
yBytes = append(make([]byte, byteLen-len(yBytes)), yBytes...)
|
||||
|
||||
// 添加 "04" 前缀
|
||||
publicKeyBytes := append([]byte{0x04}, append(xBytes, yBytes...)...)
|
||||
|
||||
return strings.ToUpper(hex.EncodeToString(publicKeyBytes))
|
||||
}
|
||||
|
||||
func addNewline(str string) string {
|
||||
lineLength := 76
|
||||
var result strings.Builder
|
||||
for i := 0; i < len(str); i++ {
|
||||
if i > 0 && i%lineLength == 0 {
|
||||
result.WriteString("\r\n")
|
||||
}
|
||||
result.WriteByte(str[i])
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
func sign(merchantId string, privateKeyHex string, signContent string) (string, error) {
|
||||
privateKey, err := sm2.ReadPrivateKeyFromHex(privateKeyHex)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
r, s, err := sm2.Sm2Sign(privateKey, []byte(signContent), []byte(merchantId), rand.Reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return rSToSign(r, s), nil
|
||||
}
|
||||
|
||||
func verify(content string, signature string, publicKeyStr string, merchantId string) bool {
|
||||
pubKey, err := sm2.ReadPublicKeyFromHex(publicKeyStr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("pubKeyBytes sm2 ReadPublicKeyFromHex err: %v", err))
|
||||
}
|
||||
r, s := signToRS(signature)
|
||||
return sm2.Sm2Verify(pubKey, []byte(content), []byte(merchantId), r, s)
|
||||
}
|
||||
|
||||
func signToRS(signStr string) (*big.Int, *big.Int) {
|
||||
signSub := strings.Split(signStr, "#")
|
||||
if len(signSub) != 2 {
|
||||
panic(fmt.Sprintf("err rs: %x", signSub))
|
||||
}
|
||||
r, _ := new(big.Int).SetString(signSub[0], 16)
|
||||
s, _ := new(big.Int).SetString(signSub[1], 16)
|
||||
return r, s
|
||||
}
|
||||
|
||||
func rSToSign(r *big.Int, s *big.Int) string {
|
||||
rStr := r.Text(16)
|
||||
sStr := s.Text(16)
|
||||
return fmt.Sprintf("%s#%s", rStr, sStr)
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package sm4
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
SELF_PRI = "47388B05A25F7EF05C6B663583AEB2F8C0CB87A4E77F3AB55B58AC51E60CDB31"
|
||||
|
||||
SELF_PUB = "044EE2F16F090E28F5BC2A1F6F9148784FBB285E219AC9CC0DF59054C36A12C42B022E56D7B89ED394A0B47D8FBBB2551F09ED64C483C2FDA426D47EADCB952C58"
|
||||
|
||||
PARTY_PRI = "8843AB53E99C31E1057C6183842472DE476E77200EE6BB79AA4FEB3521BD31CB"
|
||||
|
||||
PARTY_PUB = "0475904CB1A2F66077E964174995B319B0F1FA1DC593D57D5E7351B5E56F4E4E2E114D9A4234F66D799055566231170467EDA908E124D91FF826589A7CCE7450DA"
|
||||
)
|
||||
|
||||
func TestGenerateKey(t *testing.T) {
|
||||
hexPri, publicKeyHex := GenerateKey()
|
||||
fmt.Println(hexPri, publicKeyHex)
|
||||
}
|
||||
|
||||
func TestSM4Encrypt(t *testing.T) {
|
||||
t.Log(encrypt())
|
||||
}
|
||||
|
||||
func TestSM4Decrypt(t *testing.T) {
|
||||
|
||||
//uid, en := encrypt()
|
||||
uid := "7c0756edc19e4c87aa7c628583e8eab7"
|
||||
en := "eyJhY2Nlc3NUb2tlbiI6IkI4NjY5QUU5QzU4MDI0MTJBQkEwREJCQkU0M0ExREE5IiwiZW5jcnlwdEtleSI6IjA0RUQ0RUNEQzMwOTEyMEREQjUwMTc2RjgzM0IzQ0ZFMUVDNTY3Q0Q3OEY1MDM3RkNERTNGRDNDMTVENzZDRDFFRTE1REQ0MjY5NjFENUQ0NzRFMDlBNTVFNzEyMjdBMUQ0RDEzNkQ5QUM0ODMwMzNBNDE3RTQ4MTczODcwQjI4Qjk2OEM2ODAyMjAzRTZDRjVEN0VDMzNGRjg2QjE0QjIyRDdERjdDRTc1REM2M0M0QjM5MzdFNEYyMjkwRTYwODdFMzY3NDNCOTNEMTNCMTJGNEQwOTY4NDM5NTc1QTI5RTIiLCJyZXF1ZXN0Ijoid0JmcDE5Q3luWGtFZ082SEJwMXpsVHQxR0pQL1RicDhGQ1AvTUtiVE85S0h0cWEvdXpsV2Mwakh6NGM4Wm5yRWQ1d0ZSMk9CaFBHcFxyXG50L1NveGFXTjlIZ3F6ZDJ1QWdBWjRlS2FTU3NiZG1nbVBFRDEvVHgwNVgvQ1BmZ1ZXZnVMRS9STjBVeUFKYWJBaHdqdFpBdzFUQ2pHXHJcbkdPcXJqdHFqRDVodVUxU2xOdmxSV2R5WVFucy9aeE9pTFBtSUF4UE51Y2JIcXJKVTNBS2VtQ0R6NWZybzFpdjBWSmR3TitxTU5taytcclxuR0krdXNRbHpvcFJTeW0zWFBmMzRlcTdUM0RLNjY0TUowY1BMVW1UOTdKS05TU0dDRWx4aUhBczZWeTBqVU9zZExpOEhKejdrdWVmZFxyXG55b0h4RWVBcjRCb2dOYUJaSXovamQ3bHdmTUpNOVBqOVJvOHpFcU9iNFM1RG1iUW12UEF6SzVweEZkT2U4WUpSeElwUnhxd1ZIYzdMXHJcblkrWVN2S2NqUGNXanE2N2QrOFJXMFpWNUNpZldjQWtDVGRQWlN3ZklaZUFIc2VNcS9zVk9xOXRqNW1lL0NPNWJsZU9KV0picmJ6RWdcclxuWVJNK2grMU11cTNwcDNKNDVtWVpzY1VDeEo5S0dCYjlyWUlzT1N6dDdtRlpkZXdvckJDQkQvc1pvSG1OWG1DMzBBTWh0azIyVmsvTFxyXG5uWCtTSm05aWZ4amROYlNRK1lDTXY3RXp3TlVHOVVONTUzTTVUN3J1T0M5RlBWbXJmc2lpZVYrMENyWC92TUJ6cFpKcnpZZWI1aHlaXHJcbmthWXozNXFnaExGQ0hvOWNQdE9GNUo4Z2xoUzRUWFFaUk96NFhZMlp6bHBKcWF4cGhpUyt4ZGhtazlURmdnemZnODNKN1BwVnM4U21cclxuTXN5U1JCUGtRL0kxZVBmaXVMSmtlSklPa0lXTWtIbFRvMFVoOEd0SDlRREc3SHpGb3lVZWNyTld6eGFjcmxTNjRXQ0Njam1aODlXaVxyXG5ZODh6TGFtSCtFeWptZGc5L24wTWFrQytjL3FtWFBLN29xZDhnSWVvNFFXTUEvSHFGVi9zemJZYU5EVUJ5b3JXdmdSUjFpL3dvQVF3XHJcbkdMTlVQQmtkby9Nd2tNRkF4R0hOYlBSRG9tc0piNEpUdUNSVW1LejFuUjltNU5rT0c3TGJWcDFLSytCcDdKbzQ2MmxCQ1phYlRxYkRcclxuckNmbWpGR21Vb1RYdHVUUU13VEFuMThUNTNIdTZ4dnlKVjVGcHA2VmdKdkFDdGdJQVZCa0JHOFNwRzB5K2ZDOGlSK1pFZ0FJR0ZhT1xyXG5VZ2FtWjN3WVBLSzE5MmI2bkdFYjY2YlA1VmV2cXpNcmZrbk0rT2k3YmtnVVZhdmdFekluZ1loQmpDMng4OFBZVkpYamxtRmVOTjNaXHJcbklEMFFJWlc1aWc5WSt2cTJ6NFhhZ3RQZ2gyVk9pZlZvMnIwc1ZGN2hNWUVGSDFwdHo2bjc5T01MeWhqOTdZMXJMTGNwa1RyNkttQ3Vcclxuemt2V3lHNm01ZTRrYmxnbVRhcFJ4TkIyZmZKR3JGT3lyYkhjVncrcHFDRHZtTVErRC8xQkxOa3ZnNU5PdFBzRWQ5RGJGeXNrTnlpQ1xyXG5iemp0N0J3elRaZjdYTXVYNE5pbmRJZElYUWxoT2NJMkdiZ2NBQm9WaHFzOGVUNnN4d0xNK21YUG5Xejc5TXN4U3VSWDlvaURYelZJXHJcbjhtVktqb2ZOVXdwSTRKdUF4SUlFRGROcDh4RlVRbnFOQkU0aXcrTjNmQlUydnB1Slk1L3dKbGtWOUVlelU1Z3Q1YS9lNzdyR21sTXVcclxuRDViNTdxYkJMQVFFbFprVnZqRFdZbjZQT3VjTGJEaElidS9ia1ZTNElYL1FoemxUM0s3TnEvK2I1QkdVbThIdy9NQlNyTXJORzRzcFxyXG5Ua2dJYW56ZnJWSDFIYXBTdUprS0NwOVMrd3hEV3R5N01TeXFsUGdEc1d5aTRZRE96aHYzZlBJUXU5NzFSQWJWMkVXVlROSXpnUFJOXHJcbkNxalNPN2RyUVJyQ1hUQlZwU1R0bDZac2UrV1ZqNndmSkZjN1J6ZFpKWHJ4MnZ5SnR5ZDczVG90Tll0Y1QwQmVDUzhacUVjdTRQbW5cclxuK0RmRUR6cmNoOGliZ1MxS2lGV3BtMFVQSG05dzM5dG42S2NYRncvM0psbnRMNVZvbFYrRGxpbW5TNkEzN0hiNm9FT0FhU3NJRVhLK1xyXG5VTjBOZ0tQVzRoNm9qS3FkSi9HZXVuV1FEUTlRYWxyWXgwYzk1alAvL0FyZitlalA2cnErWmxFUHRGZ1VqaDI5WTNKSlBLZVNZU3kzXHJcbnRRdDdoL2NiM0RqbFBRTlJvMG5PTUZVaEJ0MUQzcE41SG5CeEZPcUpuMk13bVU2RVV3KzF3Y0xVd0J3dUo2VXhXbk15MUNaa29PaFlcclxuVGtCdUFJTTZuY01NV3hEc1F4YklJS212dE5nWFZ0eXJmMDBzSGpGczJUeVpqY1dmTFB5bEZieXZzR2ZQU3BnN2xYS0dmOUI5UW13OVxyXG5nTUdaMUtjQ3ZpTVIrT2dSREovNU9CbGltWkdrUExhNWtBN2FNUEQ3S2xMWlhpSDNDLzVyeWd0ekNXemUzZmc2MW5LaUdSdncrVVQzXHJcbncra01NdFd0ZFZZckdSZUN5cnc5dndzUWlORkt2ZWJxTWFZNXVQeU1aZklmcnhGWE1OazM5Z2NjMis2KzVXZ0lGaGhha0lPNFhuQitcclxuRVkrQnI2cDhXSjVVSTZST2t5aER1UE9pY2wzbXJkaTlqM3RwL1FoTkdFVldid1lSSHlnRGhUV0FhanV6UUo0S01zUEZSZy9DOE90QlxyXG5BcGpHVmZSSlhBQWppY1kzL08rTjJudmtzYVc0eUtoMStTang0c0ZpYUhkc0VCUFpXdkxSTGdENWJFOHBmcUo1dGJjRjR4ZmNXSGNpXHJcbmVLSldtcjJxOU5JdmhZdnFhSHZBc1RsMmFTWUJCWDZIYTdLL2IrL2VmSFp6ZDcxZ3RCQ2tCTmM3ejNPd0YrRjB4VzJBSnVsbXc1b3hcclxuczRhQmpSU25uWmVyQ0pxMnd6VkpjQ05OZnU5ZTZpWnZnK0M4MHh5cFdQaDNsQVZxVmY5VjNOcHVyWFkyc3QvQnQ3WURSMnNCd3RLM1xyXG5CV3RydUVUMm9NVTl4YmNmK3dEdmhyajE1eGtvNXNBcXpYUnhCaFZYTTlOQVhldFl3Y21GVE5ITlhieVY1bzNZckhjeHh2RnJNQmFrXHJcbnJoTUg4S3dHYWpTRFFjOW95NnFqbTdhUTA2Uk1GMjlONmNXRFRHUENMT1BVUE4vamQvVGdVM0lRQ1VuWm95Q01vT1p6Z2ZtTnYrS0pcclxuTWRIMmZneUIzdzljQzRqZTFpTHA0ZHpaVng1QnJtMTNjSDh1bnoyNVczeGdnQWgwRCs1WHpLalB0UDZpVFo0U0hsUXdNREs5b3FzOVxyXG5RdkVISHg3UFAxd2FhYnVQaFp1TE1BdFRPNENOaWpUMFExdktUVlBwZ1ZiMCtFbVpGVnMxSlk0NGNZUWFmT0w2NXFEZGZYZG43VlFUXHJcblBjV2xBQVVpSEthWjh3WlE0aSs1cG1ZUUFkclF6cVpGTm43U2hoZXlRNDd6QjJwbS95NjFncWt4a3MvcEV6RnBYZWhNQjRmeTVsczhcclxuTkFqS1IwemhTaE1LVEpNSlAvVENPV2d5RFh1dkd1YloyNGpML1FzQzVrT2xMKzNXeDlRWEZzQ0tKb3FtVlJRZFVBT004L3N6SWN3elxyXG44anJZZXlwZ0tWYkw0TTdxaDRUS2ZlSVJ5cG90RzczWG4yS3Y1bjg1ZWdUT0FuY29uTEYzcEpwb0JEb25pTElqcExNUXBFeWVvTmxqXHJcbkphK01VcXd0bEs0ZGJOb1kzQkh1ZUZMTkFGYW90cmlEVWdXbmdJQlNta0VMRzdjQVNxdndhZjNUbnduR2orL0U4K3puTmRKUkdPTDVcclxuWlhDaWF3N1BHVXJhTGgvVmhab3hUWGYyNnpNMzZzQXZocjFuWlpKT1UwMVhVc3pQc1Bhc3NJanIvTDhSMVp5NXJ6U2ZvTzI1UnI0dlxyXG5nL0pGd0FDU1BGRWd6cnVOY081TVF1ZFRPTHEySFhLSiIsInNpZ25hdHVyZSI6IjExNGYxNzE4NWVmODI0Mjk0MDY2ZDViNzZhMzVlMjhkZjQ1MjA4YzkxZjk1NzU1M2Q4YWRjMWRmZjU2MDJmMDYjNzljNDc4ZTY3MmM4YTFmMzQ3OWQzY2U4YzQ0YTljMGM3YWI0NmExOTFjYWZjYzY5MzZhZjcwZDlkMTQzYzJhMiJ9"
|
||||
enstr, _ := base64.StdEncoding.DecodeString(en)
|
||||
decrypt, err := Sm4Decrypt(uid, PARTY_PRI, PARTY_PUB, string(enstr), true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Log(decrypt)
|
||||
}
|
||||
|
||||
func encrypt() (string, string) {
|
||||
//uid := strconv.FormatInt(int64(5476377146882523149), 10)
|
||||
uid := "7c0756edc19e4c87aa7c628583e8eab7"
|
||||
data := "{}"
|
||||
en, err := Sm4Encrypt(uid, PARTY_PRI, PARTY_PUB, data, "", true)
|
||||
base64Json := base64.StdEncoding.EncodeToString([]byte(en))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%s\n", base64Json)
|
||||
return uid, en
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
module gitea.cdlsxd.cn/self-tools/l_crypt
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/ZZMarquis/gm v1.3.2
|
||||
github.com/tjfoc/gmsm v1.4.1
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee // indirect
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||
)
|
|
@ -0,0 +1,37 @@
|
|||
package encrypt
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const lettersString = "0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
|
||||
|
||||
// 字符串长度
|
||||
const number = 16
|
||||
|
||||
/*
|
||||
16位码,前15位随机字符串,最后一位通过前15位字符串计算校验生成
|
||||
*/
|
||||
|
||||
func LotteryEncryptEncode() string {
|
||||
b := make([]byte, number)
|
||||
var sum byte
|
||||
for i := 0; i < number-1; i++ {
|
||||
b[i] = lettersString[rand.Int63()%int64(len(lettersString))]
|
||||
sum += b[i]
|
||||
}
|
||||
b[number-1] = lettersString[sum%byte(len(lettersString))]
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
||||
func LotteryEncryptDecode(str string) bool {
|
||||
var sum byte
|
||||
for i := 0; i < len(str)-1; i++ {
|
||||
sum += str[i]
|
||||
}
|
||||
if lettersString[sum%byte(len(lettersString))] != str[len(str)-1] {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package encrypt
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLotteryEncryptEncode(t *testing.T) {
|
||||
code := LotteryEncryptEncode()
|
||||
t.Log(code)
|
||||
}
|
||||
|
||||
func TestLotteryEncryptDecode(t *testing.T) {
|
||||
code := LotteryEncryptEncode()
|
||||
t.Log(code)
|
||||
result := LotteryEncryptDecode(code)
|
||||
t.Log(result)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package l_encrypt
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/rsa"
|
||||
)
|
||||
|
||||
func NewRsa(app *AppEncrypt) ApiCrypt {
|
||||
return &Rsa{
|
||||
App: app,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Rsa) Encrypt(data string) (encryptData []byte, err error) {
|
||||
if r.App.MerchantPublicKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
publicKeyPEM := `-----BEGIN PUBLIC KEY-----
|
||||
` + r.App.MerchantPublicKey + `
|
||||
-----END PUBLIC KEY-----`
|
||||
encryptByte, err := rsa.Encrypt(publicKeyPEM, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Rsa加密失败")
|
||||
}
|
||||
encryptData = []byte(base64.StdEncoding.EncodeToString(encryptByte))
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Rsa) Decrypt(encryptData string) (decryptData []byte, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("Rsa解密失败")
|
||||
}
|
||||
}()
|
||||
if r.App.PrivateKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
|
||||
` + r.App.PrivateKey + `
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
decryptData, err = rsa.Decrypt(privateKeyPEM, encryptData)
|
||||
if err != nil || decryptData == nil {
|
||||
return nil, fmt.Errorf("Rsa解密失败")
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package l_encrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/sm2"
|
||||
)
|
||||
|
||||
func NewSm2(app *AppEncrypt) ApiCrypt {
|
||||
return &SM2{
|
||||
App: app,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SM2) Encrypt(data string) (encryptData []byte, err error) {
|
||||
|
||||
if r.App.MerchantPublicKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
|
||||
encryptDataString, err := sm2.SM2Encrypt(data, r.App.MerchantPublicKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("加密失败")
|
||||
}
|
||||
encryptData = []byte(encryptDataString)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *SM2) Decrypt(encryptData string) (decryptData []byte, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("解密失败")
|
||||
}
|
||||
}()
|
||||
if r.App.PrivateKey == "" || r.App.PublicKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
|
||||
decryptDataString, err := sm2.SM2Decrypt(encryptData, r.App.PublicKey, r.App.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解密失败")
|
||||
}
|
||||
decryptData = []byte(decryptDataString)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package l_encrypt
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/self-tools/l_crypt/encrypt_way/sm4"
|
||||
)
|
||||
|
||||
func NewSm4(app *AppEncrypt) ApiCrypt {
|
||||
return &SM4{
|
||||
App: app,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SM4) Encrypt(data string) (encryptData []byte, err error) {
|
||||
if r.App.MerchantPublicKey == "" || r.App.PrivateKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
encryptDataString, err := sm4.Sm4Encrypt(r.App.UniKEY, r.App.PrivateKey, r.App.MerchantPublicKey, data, "", true)
|
||||
base64Json := base64.StdEncoding.EncodeToString([]byte(encryptDataString))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("加密失败")
|
||||
}
|
||||
encryptData = []byte(base64Json)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *SM4) Decrypt(encryptData string) (decryptData []byte, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("解密失败")
|
||||
}
|
||||
}()
|
||||
if r.App.PrivateKey == "" || r.App.MerchantPublicKey == "" {
|
||||
return nil, fmt.Errorf("密钥缺失")
|
||||
}
|
||||
entry, _ := base64.StdEncoding.DecodeString(encryptData)
|
||||
encryptData = string(entry)
|
||||
decryptDataString, err := sm4.Sm4Decrypt(r.App.UniKEY, r.App.PrivateKey, r.App.MerchantPublicKey, encryptData, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解密失败")
|
||||
}
|
||||
decryptData = []byte(decryptDataString)
|
||||
return
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package l_encrypt
|
||||
|
||||
type (
|
||||
ApiCrypt interface {
|
||||
Encrypt(data string) (encryptData []byte, err error)
|
||||
Decrypt(encryptData string) (decryptData []byte, err error)
|
||||
}
|
||||
|
||||
Rsa struct {
|
||||
App *AppEncrypt
|
||||
}
|
||||
|
||||
SM2 struct {
|
||||
App *AppEncrypt
|
||||
}
|
||||
|
||||
SM4 struct {
|
||||
App *AppEncrypt
|
||||
}
|
||||
|
||||
AES struct {
|
||||
App *AppEncrypt
|
||||
}
|
||||
|
||||
AppEncrypt struct {
|
||||
UniKEY string
|
||||
MerchantPublicKey string
|
||||
PublicKey string
|
||||
PrivateKey string
|
||||
}
|
||||
)
|
||||
|
||||
var apiCryptMap = map[cryptType]func(en *AppEncrypt) ApiCrypt{
|
||||
CryptRSA: NewRsa,
|
||||
CryptSM2: NewSm2,
|
||||
CryptSM4: NewSm4,
|
||||
CryptAES: NewAES,
|
||||
}
|
||||
|
||||
func Crypt(ct cryptType) (cryptFunc func(app *AppEncrypt) ApiCrypt) {
|
||||
return apiCryptMap[ct]
|
||||
}
|
Loading…
Reference in New Issue