登录
原创

银行卡三要素核验(SM2+SM4国密加密版)- 聚合数据API调用Golang示例

发布于 2026-01-07 阅读 115
  • 后端
  • Go
  • 聚合数据
原创

环境配置

  • Go 1.19+
  • 系统级 GmSSL 库
    • macOS: brew install gmssl
    • Ubuntu/Debian: sudo apt-get install libgmssl-dev
    • CentOS/RHEL: sudo yum install gmssl-devel

项目文件

demo
├── go.mod      
├── go.sum          
├── main.go         
└── public_key.pem  # SM2公钥:联系商务获取

核心代码

package main

import (
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"strings"

	gmssl "github.com/GmSSL/GmSSL-Go"
)

// sm4EncryptCBC 使用SM4-CBC加密数据并返回Base64编码结果
func sm4EncryptCBC(plaintext, key, iv string) (string, error) {
	// 使用GmSSL-Go的SM4-CBC加密功能
	sm4Cbc, err := gmssl.NewSm4Cbc([]byte(key), []byte(iv), true) // true表示加密
	if err != nil {
		return "", fmt.Errorf("创建SM4-CBC加密器失败: %v", err)
	}

	// 加密数据
	ciphertext, err := sm4Cbc.Update([]byte(plaintext))
	if err != nil {
		return "", fmt.Errorf("SM4-CBC加密失败: %v", err)
	}

	// 完成加密(处理填充)
	finalBlock, err := sm4Cbc.Finish()
	if err != nil {
		return "", fmt.Errorf("SM4-CBC完成加密失败: %v", err)
	}

	// 合并加密结果
	fullCiphertext := append(ciphertext, finalBlock...)

	// Base64编码
	return base64.StdEncoding.EncodeToString(fullCiphertext), nil
}

// generateRandomSm4KeyAndIv 随机生成SM4密钥和IV(各16字节),返回十六进制字符串
func generateRandomSm4KeyAndIv() (string, string, error) {
	// 生成16字节的随机密钥
	keyBytes := make([]byte, 16)
	if _, err := rand.Read(keyBytes); err != nil {
		return "", "", fmt.Errorf("生成随机SM4密钥失败: %v", err)
	}

	// 生成16字节的随机IV
	ivBytes := make([]byte, 16)
	if _, err := rand.Read(ivBytes); err != nil {
		return "", "", fmt.Errorf("生成随机SM4 IV失败: %v", err)
	}

	// 转换为十六进制字符串
	keyHex := hex.EncodeToString(keyBytes)
	ivHex := hex.EncodeToString(ivBytes)

	return keyHex, ivHex, nil
}

func main() {
	// 导入SM2公钥(用于加密SM4密钥和IV)
	publicKey, err := gmssl.ImportSm2PublicKeyInfoPem("./public_key.pem")
	if err != nil {
		log.Fatalf("导入SM2公钥失败: %v", err)
	}

	// 基本参数配置
	apiUrl := "http://v.juhe.cn/verifybankcard3/queryEncrySm"
	apiKey := "12345678ba6e7a05938e6b4a12345678"

	// 1. SM4密钥和IV,随机生成16字节
	sm4KeyHex, sm4IvHex, err := generateRandomSm4KeyAndIv()
	if err != nil {
		log.Fatalf("生成随机SM4密钥和IV失败: %v", err)
	}

	sm4KeyBytes, _ := hex.DecodeString(sm4KeyHex)
	sm4IvBytes, _ := hex.DecodeString(sm4IvHex)

	// 2. 使用SM2公钥加密SM4密钥和IV,并Base64编码
	sm4KeyEncrypted, err := publicKey.Encrypt(sm4KeyBytes)
	if err != nil {
		log.Fatalf("SM2加密SM4密钥失败: %v", err)
	}
	sm4IvEncrypted, err := publicKey.Encrypt(sm4IvBytes)
	if err != nil {
		log.Fatalf("SM2加密SM4 IV失败: %v", err)
	}

	sm4KeyBase64 := base64.StdEncoding.EncodeToString(sm4KeyEncrypted)
	sm4IvBase64 := base64.StdEncoding.EncodeToString(sm4IvEncrypted)

	// 原始数据
	originalData := map[string]string{
		"realname": "李洋",
		"idcard":   "370820199001151312",
		"bankcard": "6225880212345678",
	}

	// 3. 使用SM4-CBC加密敏感数据
	encryptedData := make(map[string]string)
	for key, value := range originalData {
		encrypted, err := sm4EncryptCBC(value, string(sm4KeyBytes), string(sm4IvBytes))
		if err != nil {
			log.Fatalf("SM4加密%s失败: %v", key, err)
		}
		encryptedData[key] = encrypted
	}

	// 接口请求入参配置
	requestParams := url.Values{}
	requestParams.Set("key", apiKey)
	requestParams.Set("sm4Key", sm4KeyBase64)
	requestParams.Set("sm4Iv", sm4IvBase64)
	requestParams.Set("realname", encryptedData["realname"])
	requestParams.Set("idcard", encryptedData["idcard"])
	requestParams.Set("bankcard", encryptedData["bankcard"])

	// 发起接口网络请求
	resp, err := http.Post(apiUrl, "application/x-www-form-urlencoded", strings.NewReader(requestParams.Encode()))
	if err != nil {
		log.Fatalf("网络请求异常: %v", err)
	}
	defer resp.Body.Close()

	// 读取原始响应body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalf("读取响应失败: %v", err)
	}

	fmt.Println(string(body))
}

编译运行

# 设置 GmSSL 头文件和库路径(macOS Homebrew 示例)
export CGO_CFLAGS="-I/opt/homebrew/Cellar/gmssl/3.1.1/include"
export CGO_LDFLAGS="-L/opt/homebrew/Cellar/gmssl/3.1.1/lib"

# 运行程序
go run main.go

正常情况下会输出类似信息:

{"reason":"成功","result":{"res":2,"message":"认证信息不匹配,银行卡无效","jobid":"JH2071260107144558876159mT"},"error_code":0}

参考资料

评论区

admin
15粉丝

打江山易,守江山难,负重前行,持续创新。

0

0

4

举报