Files
2025-11-24 16:06:44 +08:00

282 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Net.Http;
using System.Threading.Tasks;
public class Program
{
// ==================== 配置区域 ====================
// 请根据实际情况修改以下配置参数
// AES加密密钥 (16进制字符串32位)
// API接口配置
private const string InterfaceName = "XXXXXXXX"; // 接口编号
private const string AccessId = "XXXXXXXXXXX"; // 访问ID
private const string EncryptionKey = "XXXXXXXXXXXXXXXXXXX"; // 加密密钥
private const string BaseUrl = "https://api.tianyuanapi.com"; // API基础URL
// 测试数据配置
private const string TestMobileNo = "13700000000"; // 测试手机号
private const string TestIdCard = "XXXXXXXXXXXXX"; // 测试身份证号
private const string TestName = "XXXXXXXX"; // 测试姓名
private const string TestAuthDate = "20250318-20270318"; // 测试授权日期
// HTTP请求配置
private const int RequestTimeout = 30000; // 请求超时时间(毫秒)
// ==================== 主程序 ====================
public static async Task Main()
{
Console.WriteLine("===== AES CBC 加密解密演示 =====");
// 1. 创建一个JSON对象
var data = new
{
mobile_no = TestMobileNo
};
// 将JSON对象序列化为字符串
string jsonString = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine("\n原始JSON:");
Console.WriteLine(jsonString);
// 2. 加密JSON
Console.WriteLine("\n开始加密...");
string encryptedJson = Encrypt(jsonString);
Console.WriteLine($"加密成功! 加密后Base64:");
Console.WriteLine(encryptedJson);
// 3. 解密JSON
Console.WriteLine("\n开始解密...");
string decryptedJson = Decrypt(encryptedJson);
Console.WriteLine($"解密成功! 解密后的原始JSON:");
Console.WriteLine(decryptedJson);
// 4. 验证加解密一致性
Console.WriteLine("\n验证结果:");
if (jsonString == decryptedJson)
{
Console.WriteLine("✅ 加解密前后内容完全一致");
// 验证原始数据是否可用
Console.WriteLine("\n尝试解析解密后的JSON:");
try
{
var deserializedObject = JsonSerializer.Deserialize(decryptedJson, typeof(object));
Console.WriteLine($"✅ JSON解析成功类型: {deserializedObject.GetType()}");
}
catch (Exception ex)
{
Console.WriteLine($"❌ JSON解析失败: {ex.Message}");
}
}
else
{
Console.WriteLine("❌ 加解密前后内容不一致!");
Console.WriteLine("原始长度: " + jsonString.Length);
Console.WriteLine("解密后长度: " + decryptedJson.Length);
// 找出第一个不同的位置
for (int i = 0; i < Math.Min(jsonString.Length, decryptedJson.Length); i++)
{
if (jsonString[i] != decryptedJson[i])
{
Console.WriteLine($"第一个差异在位置 {i}:");
Console.WriteLine($"原始字符: '{jsonString[i]}' ({(int)jsonString[i]})");
Console.WriteLine($"解密字符: '{decryptedJson[i]}' ({(int)decryptedJson[i]})");
break;
}
}
}
// 5. 演示API调用流程可选
Console.WriteLine("\n===== 演示API调用流程 =====");
await DemonstrateApiCall();
}
// ==================== AES加密解密方法 ====================
/// <summary>
/// AES CBC 加密函数
/// 使用PKCS7填充随机IV返回Base64编码的密文
/// </summary>
/// <param name="plainText">要加密的明文</param>
/// <returns>Base64编码的密文</returns>
public static string Encrypt(string plainText)
{
byte[] key = HexToBytes(EncryptionKey);
using Aes aes = Aes.Create();
aes.Key = key;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.GenerateIV();
byte[] iv = aes.IV;
using ICryptoTransform encryptor = aes.CreateEncryptor();
using MemoryStream ms = new();
// 先写入IV
ms.Write(iv, 0, iv.Length);
using (CryptoStream cs = new(ms, encryptor, CryptoStreamMode.Write))
using (StreamWriter sw = new(cs))
{
sw.Write(plainText);
}
return Convert.ToBase64String(ms.ToArray());
}
/// <summary>
/// AES CBC 解密函数
/// 从Base64密文中提取IV和密文数据进行解密
/// </summary>
/// <param name="cipherText">Base64编码的密文</param>
/// <returns>解密后的明文</returns>
public static string Decrypt(string cipherText)
{
byte[] key = HexToBytes(EncryptionKey);
byte[] fullData = Convert.FromBase64String(cipherText);
// 提取前16字节作为IV
byte[] iv = new byte[16];
Buffer.BlockCopy(fullData, 0, iv, 0, iv.Length);
// 实际密文数据
byte[] cipherData = new byte[fullData.Length - 16];
Buffer.BlockCopy(fullData, 16, cipherData, 0, cipherData.Length);
using Aes aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using ICryptoTransform decryptor = aes.CreateDecryptor();
using MemoryStream ms = new(cipherData);
using CryptoStream cs = new(ms, decryptor, CryptoStreamMode.Read);
using StreamReader sr = new(cs);
return sr.ReadToEnd();
}
/// <summary>
/// 将16进制字符串转换为字节数组
/// </summary>
/// <param name="hex">16进制字符串</param>
/// <returns>字节数组</returns>
private static byte[] HexToBytes(string hex)
{
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
// ==================== API调用演示方法 ====================
/// <summary>
/// 演示完整的API调用流程
/// 包括:参数构建、加密、发送请求、接收响应、解密响应
/// </summary>
private static async Task DemonstrateApiCall()
{
try
{
// 构建完整的API URL
string url = $"{BaseUrl}/api/v1/{InterfaceName}";
// 构建请求参数
var apiParams = new
{
mobile_no = TestMobileNo,
id_card = TestIdCard,
auth_date = TestAuthDate,
name = TestName
};
// 将参数转换为JSON字符串并加密
string jsonStr = JsonSerializer.Serialize(apiParams);
Console.WriteLine($"请求参数: {jsonStr}");
string encryptedData = Encrypt(jsonStr);
Console.WriteLine($"加密后的数据: {encryptedData}");
// 构建请求体
var payload = new { data = encryptedData };
string requestBody = JsonSerializer.Serialize(payload);
Console.WriteLine($"发送请求到: {url}");
// 发送HTTP请求
using (var httpClient = new HttpClient())
{
// 设置请求头
httpClient.DefaultRequestHeaders.Add("Access-Id", AccessId);
httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
// 设置超时时间
httpClient.Timeout = TimeSpan.FromMilliseconds(RequestTimeout);
var content = new StringContent(requestBody, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(url, content);
Console.WriteLine($"响应状态码: {response.StatusCode}");
if (response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine($"API响应: {responseBody}");
// 解析响应
try
{
var responseData = JsonSerializer.Deserialize<JsonElement>(responseBody);
if (responseData.TryGetProperty("code", out var codeElement))
{
int code = codeElement.GetInt32();
string message = responseData.TryGetProperty("message", out var msgElement) ? msgElement.GetString() : "";
string encryptedResponse = responseData.TryGetProperty("data", out var dataElement) ? dataElement.GetString() : "";
Console.WriteLine($"API响应码: {code}");
Console.WriteLine($"API消息: {message}");
if (code == 0 && !string.IsNullOrEmpty(encryptedResponse))
{
// 解密响应数据
try
{
string decryptedResponse = Decrypt(encryptedResponse);
Console.WriteLine($"解密后的响应: {decryptedResponse}");
}
catch (Exception ex)
{
Console.WriteLine($"解密响应数据失败: {ex.Message}");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"解析响应失败: {ex.Message}");
}
}
else
{
Console.WriteLine($"请求失败: {response.StatusCode}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"API调用异常: {ex.Message}");
}
}
}