306 lines
6.9 KiB
Go
306 lines
6.9 KiB
Go
|
|
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)
|
|||
|
|
}
|
|||
|
|
}
|