From 0963b55fe9850db89bb7dcc3054a3a4c736c4038 Mon Sep 17 00:00:00 2001 From: Falcon <12919280+falconfly@user.noreply.gitee.com> Date: Mon, 3 Nov 2025 11:55:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0hash=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PrivateBox/DataContext/CrytionItem.cs | 2 +- PrivateBox/EncryptionService.cs | 51 ++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/PrivateBox/DataContext/CrytionItem.cs b/PrivateBox/DataContext/CrytionItem.cs index a664b0a..e9d2a23 100644 --- a/PrivateBox/DataContext/CrytionItem.cs +++ b/PrivateBox/DataContext/CrytionItem.cs @@ -16,7 +16,7 @@ namespace PrivateBox.DataContext /// /// 加密项值 /// - [SqlSugar.SugarColumn(ColumnDataType ="text")] + [SqlSugar.SugarColumn(ColumnDataType = "text")] public string? ItemValue { get; set; } } } diff --git a/PrivateBox/EncryptionService.cs b/PrivateBox/EncryptionService.cs index b889929..42c92b2 100644 --- a/PrivateBox/EncryptionService.cs +++ b/PrivateBox/EncryptionService.cs @@ -1,4 +1,5 @@ using System.Security.Cryptography; +using System.Text; /// /// 加密解密服务接口 @@ -76,9 +77,8 @@ public class AesEncryptionService:IEncryptionService byte[] result = new byte[encryptedData.Length + SaltSize]; Array.Copy(encryptedData,0,result,0,encryptedData.Length); Array.Copy(salt,0,result,encryptedData.Length,SaltSize); - - // 转换为Base64返回 - return Convert.ToBase64String(result); + var (base64, hash) = GetHash(result); + return $"{base64}${hash}"; } public string Decrypt(string cipherText,string key) { @@ -88,6 +88,20 @@ public class AesEncryptionService:IEncryptionService if(string.IsNullOrEmpty(key)) throw new ArgumentException("密钥不能为空",nameof(key)); + var result = new StringBuilder(); + if(!cipherText.Contains("$")) { + result.AppendLine("加密值不包含验证"); + } + if(cipherText.Contains("$")) { + var sp = cipherText.Split("$"); + cipherText = sp[0]; + if(sp.Length < 2 || string.IsNullOrEmpty(sp[1])) { + result.AppendLine("存在验证,但是验证码错误!"); + } + if(!ValidateBase64(sp[0],sp[1])) { + result.AppendLine("加密验证失败!信息可能被篡改!"); + } + } // 1. 转换Base64为字节数组 byte[] fullData; try { @@ -130,9 +144,10 @@ public class AesEncryptionService:IEncryptionService using(MemoryStream msDecrypt = new MemoryStream(encryptedData,16,encryptedData.Length - 16)) using(CryptoStream csDecrypt = new CryptoStream(msDecrypt,decryptor,CryptoStreamMode.Read)) using(StreamReader srDecrypt = new StreamReader(csDecrypt)) { - return srDecrypt.ReadToEnd(); + result.AppendLine(srDecrypt.ReadToEnd()); } } + return result.ToString(); } /// @@ -147,4 +162,32 @@ public class AesEncryptionService:IEncryptionService return deriveBytes.GetBytes(KeySize); } } + + /// + /// 用于hash验证的key,不可以修改,修改会导致验证失败 + /// + private readonly string hashKey = "694699FF-7157-4DF2-ACD9-E60CCFCC6007"; + + private (string base64, string hash) GetHash(byte[] bytes) { + var hk = Encoding.UTF8.GetBytes(hashKey); + using var sha256 = new HMACSHA256(hk); + byte[] hmacBytes = sha256.ComputeHash(bytes); + string hmacStr = BitConverter.ToString(hmacBytes).Replace("-","").ToLower(); + string base64 = Convert.ToBase64String(bytes); + return (base64, hmacStr); + } + + private bool ValidateBase64(string base64String,string hash) { + try { + byte[] decodedData = Convert.FromBase64String(base64String); + var hk = Encoding.UTF8.GetBytes(hashKey); + using var sha256 = new HMACSHA256(hk); + byte[] actualHashBytes = sha256.ComputeHash(decodedData); + string actualHash = BitConverter.ToString(actualHashBytes).Replace("-","").ToLower(); + return actualHash == hash; + } + catch(FormatException) { + return false; + } + } } \ No newline at end of file