6 changed files with 209 additions and 7 deletions
@ -0,0 +1,158 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO.Compression; |
|||
using System.Security.Cryptography; |
|||
using System.Text; |
|||
using System.Text.Json; |
|||
|
|||
namespace SunlightAggregationTerminal.Class |
|||
{ |
|||
public class SecureJsonService |
|||
{ |
|||
private readonly byte[] _aesKey = Encoding.UTF8.GetBytes("12345678901234567890123456789012"); |
|||
|
|||
/// <summary>
|
|||
/// 调用一:发送端处理
|
|||
/// 流程:JSON序列化 -> GZip压缩 -> AES加密 -> Base64编码
|
|||
/// </summary>
|
|||
public string CompressEncryptAndSend(object dataObject) |
|||
{ |
|||
try |
|||
{ |
|||
// 1. JSON 序列化 (使用 System.Text.Json 进行最小化处理)
|
|||
// JsonSerializerOptions 默认不包含缩进,即最小化
|
|||
string jsonString = JsonSerializer.Serialize(dataObject); |
|||
byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString); |
|||
|
|||
// 2. GZip 压缩
|
|||
byte[] compressedBytes = CompressBytes(jsonBytes); |
|||
|
|||
// 3. AES 加密
|
|||
byte[] encryptedBytes = EncryptBytes(compressedBytes); |
|||
|
|||
// 4. Base64 编码 (转为字符串以便在网络传输)
|
|||
string finalPayload = Convert.ToBase64String(encryptedBytes); |
|||
|
|||
return finalPayload; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Console.WriteLine($"发送端处理错误: {ex.Message}"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 调用二:接收端处理
|
|||
/// 流程:Base64解码 -> AES解密 -> GZip解压 -> JSON反序列化
|
|||
/// </summary>
|
|||
public T? ReceiveDecryptAndDecompress<T>(string payload) |
|||
{ |
|||
try |
|||
{ |
|||
// 1. Base64 解码
|
|||
byte[] encryptedBytes = Convert.FromBase64String(payload); |
|||
|
|||
// 2. AES 解密
|
|||
byte[] compressedBytes = DecryptBytes(encryptedBytes); |
|||
|
|||
// 3. GZip 解压
|
|||
byte[] jsonBytes = DecompressBytes(compressedBytes); |
|||
|
|||
// 4. JSON 反序列化
|
|||
string jsonString = Encoding.UTF8.GetString(jsonBytes); |
|||
T result = JsonSerializer.Deserialize<T>(jsonString); |
|||
|
|||
return result; |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
// --- 底层辅助方法 ---
|
|||
|
|||
private byte[] CompressBytes(byte[] data) |
|||
{ |
|||
using (var outputStream = new MemoryStream()) |
|||
{ |
|||
using (var gzipStream = new GZipStream(outputStream, CompressionLevel.Optimal)) |
|||
{ |
|||
gzipStream.Write(data, 0, data.Length); |
|||
} |
|||
return outputStream.ToArray(); |
|||
} |
|||
} |
|||
|
|||
private byte[] DecompressBytes(byte[] data) |
|||
{ |
|||
using (var inputStream = new MemoryStream(data)) |
|||
{ |
|||
using (var gzipStream = new GZipStream(inputStream, CompressionMode.Decompress)) |
|||
{ |
|||
using (var outputStream = new MemoryStream()) |
|||
{ |
|||
gzipStream.CopyTo(outputStream); |
|||
return outputStream.ToArray(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private byte[] EncryptBytes(byte[] data) |
|||
{ |
|||
using (Aes aes = Aes.Create()) |
|||
{ |
|||
aes.Key = _aesKey; |
|||
aes.Mode = CipherMode.CBC; |
|||
aes.Padding = PaddingMode.PKCS7; |
|||
aes.GenerateIV(); // 每次加密生成随机IV
|
|||
|
|||
var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); |
|||
|
|||
using (var ms = new MemoryStream()) |
|||
{ |
|||
// 重要:先将 IV 写入流中,以便解密时读取
|
|||
ms.Write(aes.IV, 0, aes.IV.Length); |
|||
|
|||
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) |
|||
{ |
|||
cs.Write(data, 0, data.Length); |
|||
cs.FlushFinalBlock(); |
|||
return ms.ToArray(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private byte[] DecryptBytes(byte[] data) |
|||
{ |
|||
using (Aes aes = Aes.Create()) |
|||
{ |
|||
aes.Key = _aesKey; |
|||
aes.Mode = CipherMode.CBC; |
|||
aes.Padding = PaddingMode.PKCS7; |
|||
|
|||
// 从数据开头读取 IV (AES IV 固定为 16 字节)
|
|||
byte[] iv = new byte[16]; |
|||
Buffer.BlockCopy(data, 0, iv, 0, iv.Length); |
|||
aes.IV = iv; |
|||
|
|||
var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); |
|||
|
|||
using (var ms = new MemoryStream(data, iv.Length, data.Length - iv.Length)) |
|||
{ |
|||
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) |
|||
{ |
|||
using (var resultStream = new MemoryStream()) |
|||
{ |
|||
cs.CopyTo(resultStream); |
|||
return resultStream.ToArray(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue