first commit
This commit is contained in:
305
public/examples/go/demo.go
Normal file
305
public/examples/go/demo.go
Normal file
@@ -0,0 +1,305 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ==================== 配置区域 ====================
|
||||
// 请根据实际情况修改以下配置参数
|
||||
|
||||
const (
|
||||
// API接口配置
|
||||
InterfaceName = "XXXXXXXX" // 接口编号
|
||||
AccessID = "XXXXXXXXXXX"
|
||||
EncryptionKey = "XXXXXXXXXXXXXXXXXXXXX"
|
||||
BaseURL = "https://api.tianyuanapi.com"
|
||||
|
||||
// 测试数据配置
|
||||
TestName = "XXXXXXXX"
|
||||
TestIDCard = "XXXXXXXXXXXXX"
|
||||
TestMobileNo = "XXXXXXXXXXXXXXXXXXXX"
|
||||
TestAuthDate = "20250318-20270318"
|
||||
|
||||
// HTTP请求配置
|
||||
RequestTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
// API响应结构体
|
||||
type APIResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
// 请求参数结构体
|
||||
type RequestParams struct {
|
||||
MobileNo string `json:"mobile_no"`
|
||||
IDCard string `json:"id_card"`
|
||||
AuthDate string `json:"auth_date"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// 请求载荷结构体
|
||||
type RequestPayload struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
// 结果结构体
|
||||
type Result struct {
|
||||
Code int `json:"code"`
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
EncryptedResponse string `json:"encrypted_response"`
|
||||
DecryptedResponse interface{} `json:"decrypted_response"`
|
||||
}
|
||||
|
||||
// ==================== AES加密解密方法 ====================
|
||||
|
||||
// AES CBC 加密函数,返回 Base64
|
||||
func aesEncrypt(plaintext, key string) (string, error) {
|
||||
keyBytes, err := hex.DecodeString(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(keyBytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 生成随机IV
|
||||
iv := make([]byte, aes.BlockSize)
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
paddedData := pkcs7Pad([]byte(plaintext), aes.BlockSize)
|
||||
|
||||
// 加密
|
||||
ciphertext := make([]byte, len(iv)+len(paddedData))
|
||||
copy(ciphertext, iv)
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext[len(iv):], paddedData)
|
||||
|
||||
return base64.StdEncoding.EncodeToString(ciphertext), nil
|
||||
}
|
||||
|
||||
// AES CBC 解密函数,返回解密后的明文
|
||||
func aesDecrypt(encryptedText, key string) (string, error) {
|
||||
keyBytes, err := hex.DecodeString(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ciphertext, err := base64.StdEncoding.DecodeString(encryptedText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(keyBytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(ciphertext) < aes.BlockSize {
|
||||
return "", fmt.Errorf("密文太短")
|
||||
}
|
||||
|
||||
iv := ciphertext[:aes.BlockSize]
|
||||
ciphertext = ciphertext[aes.BlockSize:]
|
||||
|
||||
if len(ciphertext)%aes.BlockSize != 0 {
|
||||
return "", fmt.Errorf("密文长度不是块大小的倍数")
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext, ciphertext)
|
||||
|
||||
// 去除填充
|
||||
unpaddedData, err := pkcs7Unpad(ciphertext)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(unpaddedData), nil
|
||||
}
|
||||
|
||||
// PKCS7填充
|
||||
func pkcs7Pad(data []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(data)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(data, padtext...)
|
||||
}
|
||||
|
||||
// PKCS7去除填充
|
||||
func pkcs7Unpad(data []byte) ([]byte, error) {
|
||||
length := len(data)
|
||||
if length == 0 {
|
||||
return nil, fmt.Errorf("数据为空")
|
||||
}
|
||||
unpadding := int(data[length-1])
|
||||
if unpadding > length {
|
||||
return nil, fmt.Errorf("无效的填充")
|
||||
}
|
||||
return data[:length-unpadding], nil
|
||||
}
|
||||
|
||||
// ==================== API调用方法 ====================
|
||||
|
||||
// 调用API函数
|
||||
func callAPI(name, idCard, mobileNo, authDate string) *Result {
|
||||
// 构建完整的API URL
|
||||
url := fmt.Sprintf("%s/api/v1/%s", BaseURL, InterfaceName)
|
||||
|
||||
// 构建请求参数
|
||||
params := RequestParams{
|
||||
MobileNo: mobileNo,
|
||||
IDCard: idCard,
|
||||
AuthDate: authDate,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
// 将参数转换为JSON字符串并加密
|
||||
jsonStr, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("JSON序列化失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("请求参数: %s\n", string(jsonStr))
|
||||
|
||||
encryptedData, err := aesEncrypt(string(jsonStr), EncryptionKey)
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("加密失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("加密后的数据: %s\n", encryptedData)
|
||||
|
||||
// 构建请求载荷
|
||||
payload := RequestPayload{
|
||||
Data: encryptedData,
|
||||
}
|
||||
|
||||
// 序列化请求载荷
|
||||
requestBody, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("请求载荷序列化失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("发送请求到: %s\n", url)
|
||||
|
||||
// 发送HTTP请求
|
||||
client := &http.Client{
|
||||
Timeout: RequestTimeout,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("创建请求失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
req.Header.Set("Access-Id", AccessID)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("请求失败: %v", err),
|
||||
}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取响应
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("读取响应失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var apiResp APIResponse
|
||||
if err := json.Unmarshal(respBody, &apiResp); err != nil {
|
||||
return &Result{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("解析响应失败: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("API响应: %s\n", string(respBody))
|
||||
|
||||
// 处理响应
|
||||
result := &Result{
|
||||
Code: apiResp.Code,
|
||||
Success: apiResp.Code == 0,
|
||||
Message: apiResp.Message,
|
||||
EncryptedResponse: apiResp.Data,
|
||||
}
|
||||
|
||||
// 如果有返回data,尝试解密
|
||||
if apiResp.Data != "" {
|
||||
decryptedData, err := aesDecrypt(apiResp.Data, EncryptionKey)
|
||||
if err != nil {
|
||||
fmt.Printf("解密响应数据失败: %v\n", err)
|
||||
result.DecryptedResponse = nil
|
||||
} else {
|
||||
var decryptedJSON interface{}
|
||||
if err := json.Unmarshal([]byte(decryptedData), &decryptedJSON); err != nil {
|
||||
fmt.Printf("解析解密后的JSON失败: %v\n", err)
|
||||
result.DecryptedResponse = decryptedData
|
||||
} else {
|
||||
result.DecryptedResponse = decryptedJSON
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ==================== 主程序 ====================
|
||||
|
||||
func main() {
|
||||
fmt.Println("===== 个人涉诉详版 =====")
|
||||
|
||||
// 调用API
|
||||
result := callAPI(TestName, TestIDCard, TestMobileNo, TestAuthDate)
|
||||
|
||||
fmt.Println("\n===== 结果 =====")
|
||||
if result.Success {
|
||||
fmt.Println("请求成功!")
|
||||
if result.DecryptedResponse != nil {
|
||||
decryptedJSON, _ := json.MarshalIndent(result.DecryptedResponse, "", " ")
|
||||
fmt.Printf("解密后的响应: %s\n", string(decryptedJSON))
|
||||
} else {
|
||||
fmt.Println("未能获取或解密响应数据")
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("请求失败: %s\n", result.Message)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user