C#實現(xiàn)WebAPI接口安全加密的具體方案
前言
在項目開發(fā)過程中,接口的安全性往往是一個容易被忽視但極其關鍵的環(huán)節(jié)。尤其是在項目上線后,面對外部攻擊、攻防演練等情況,如果沒有一套完善的加密機制,我們的數(shù)據(jù)極有可能遭受竊取或篡改。
本文介紹了一套實際項目中已落地的 Web API 安全加密方案,涵蓋了 SHA256 加簽、RSA 非對稱加密、AES 對稱加密 以及相關數(shù)據(jù)格式轉換等內容,適用于對外暴露的 API 接口保護場景。希望通過本文,能夠幫助大家構建更安全的接口通信體系。

一、方案設計
為了保障接口調用過程中的安全性,我們采用以下加密策略:
加簽(Sign):使用 SHA256 對請求參數(shù)進行簽名,防止請求內容被篡改;
加密傳輸:
- 使用 RSA 進行非對稱加密,用于加密密鑰;
- 使用 AES 進行對稱加密,用于加密實際數(shù)據(jù);
數(shù)據(jù)編碼轉換:涉及 Base64 編碼、16進制與字節(jié)數(shù)組之間的相互轉換,確保數(shù)據(jù)在網(wǎng)絡中正確傳輸和解析。
該方案不僅提升了接口的安全性,也兼顧了性能和易用性。
1、SHA256 加簽實現(xiàn)
加簽是為了驗證請求的完整性,防止請求參數(shù)在傳輸過程中被篡改。以下是 C# 實現(xiàn)的 SHA256 加簽方法:
#region 加簽SHA256
public static string GetSHA256Hash(string input)
{
using (SHA256 sha256Hash = SHA256.Create())
{
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
#endregion
通過此方法可以生成唯一的哈希值,作為請求的簽名字段附加在請求頭或參數(shù)中。
2、RSA 加密與解密
RSA 是一種非對稱加密算法,適合用于密鑰交換或數(shù)字簽名等場景。以下是 C# 中的 RSA 加解密實現(xiàn):
#region RSA加密/解密
private readonly RSA _privateKeyRsaProvider;
private readonly RSA _publicKeyRsaProvider;
private readonly Encoding _encoding;
/// <param name="encoding">編碼類型</param>
/// <param name="privateKey">私鑰</param>
/// <param name="publicKey">公鑰</param>
public RSAHelper(Encoding encoding, string privateKey, string publicKey = null)
{
_encoding = encoding;
if (!string.IsNullOrEmpty(privateKey))
{
_privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
}
if (!string.IsNullOrEmpty(publicKey))
{
_publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
}
}
// 解密
public string Decrypt(string cipherText)
{
if (_privateKeyRsaProvider == null)
{
throw new Exception("_privateKeyRsaProvider is null");
}
return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1));
}
// 加密
public string Encrypt(string text)
{
if (_publicKeyRsaProvider == null)
{
throw new Exception("_publicKeyRsaProvider is null");
}
return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.Pkcs1));
}
#endregion
客戶端使用公鑰加密敏感信息,服務端使用私鑰解密,從而保證傳輸數(shù)據(jù)的機密性。
3、AES 加密與解密
AES 是一種對稱加密算法,常用于大量數(shù)據(jù)的加密處理。以下是 C# 中的 AES 加解密示例:
#region AES加密/解密
/// <summary>
/// 加密不帶偏移量
/// </summary>
/// <param name="input"></param>
/// <param name="key">秘鑰</param>
/// <returns></returns>
public static string EncryptByAES(string input, string key)
{
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Mode = CipherMode.ECB;
rijndaelManaged.Padding = PaddingMode.PKCS7;
rijndaelManaged.FeedbackSize = 128;
byte[] data3 = Enumerable.Range(0, key.Length / 2)
.Select(x => Byte.Parse(key.Substring(x * 2, 2), NumberStyles.HexNumber))
.ToArray();
rijndaelManaged.Key = data3;
ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(input);
}
byte[] bytes = msEncrypt.ToArray();
return HexConvert.byteToHexStr(bytes);
}
}
}
}
/// <summary>
/// 返回解密后的字符串
/// </summary>
/// <param name="input"></param>
/// <param name="key">秘鑰</param>
/// <returns></returns>
public static string DecryptByAES(string input, string key)
{
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
var buffer = HexConvert.strToToHexByte(input);
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Mode = CipherMode.ECB;
rijndaelManaged.Padding = PaddingMode.PKCS7;
rijndaelManaged.FeedbackSize = 128;
byte[] data3 = Enumerable.Range(0, key.Length / 2)
.Select(x => Byte.Parse(key.Substring(x * 2, 2), NumberStyles.HexNumber))
.ToArray();
rijndaelManaged.Key = data3;
ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
using (MemoryStream msEncrypt = new MemoryStream(buffer))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srEncrypt = new StreamReader(csEncrypt))
{
return srEncrypt.ReadToEnd();
}
}
}
}
}
#endregion
AES 通常用于加密業(yè)務數(shù)據(jù)本身,結合 RSA 可以實現(xiàn)更完整的安全體系。
4、數(shù)據(jù)格式轉換工具類
為了支持不同格式的數(shù)據(jù)處理,還需要一些輔助函數(shù)來完成數(shù)據(jù)轉換:
#region 數(shù)據(jù)轉換
// 字符串轉換為字節(jié)數(shù)組
byte[] originalBytes = System.Text.Encoding.UTF8.GetBytes(originalText);
// 進行Base64編碼
string base64Encoded = Convert.ToBase64String(originalBytes);
// 進行Base64解碼
byte[] base64DecodedBytes = Convert.FromBase64String(base64Encoded);
// 字節(jié)數(shù)組轉字符串
string base64DecodedText = System.Text.Encoding.UTF8.GetString(base64DecodedBytes);
// 16進制轉base64字符串
byte[] enterpriseCode_ = HexConvert.strToToHexByte(data.enterpriseCode);
string enterpriseCode = Convert.ToBase64String(enterpriseCode_);
/// <summary>
/// 字節(jié)數(shù)組轉16進制字符串
/// </summary>
/// <param name="byteArray"></param>
/// <returns></returns>
public static string byteToHexStr2(byte[] byteArray)
{
string hexString = BitConverter.ToString(byteArray);
return hexString.Replace("-", "");
}
/// <summary>
/// 字節(jié)數(shù)組轉16進制字符串
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
/// <summary>
/// 字符串轉16進制字節(jié)數(shù)組
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static byte[] strToToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
#endregion
這些方法廣泛應用于加密前后數(shù)據(jù)格式的處理,如將加密結果轉為16進制字符串、Base64編碼等。
項目效果
通過上述加密機制,API 請求在傳輸前會經(jīng)過如下流程:
1、參數(shù)拼接并計算 SHA256 簽名;
2、敏感數(shù)據(jù)使用 AES 加密;
3、AES 密鑰使用 RSA 公鑰加密;
4、所有數(shù)據(jù)打包發(fā)送至服務端;
5、服務端使用 RSA 私鑰解密密鑰,再使用 AES 解密數(shù)據(jù),并驗證簽名。
整個流程有效防止了中間人攻擊、數(shù)據(jù)篡改和重放攻擊等問題,極大增強了接口的安全性。
總結
本文詳細介紹了在實際項目中使用的 Web API 接口安全加密方案,包括:
- 使用 SHA256 對請求參數(shù)進行簽名;
- 使用 RSA 進行非對稱加密傳輸密鑰;
- 使用 AES 進行對稱加密保護數(shù)據(jù);
- 提供了完整的 C# 示例代碼;
- 包含常用數(shù)據(jù)格式轉換方法。
這套方案已在生產(chǎn)環(huán)境中穩(wěn)定運行,具有良好的兼容性和擴展性。如果你也有類似的加密需求,歡迎交流分享你的經(jīng)驗!
最后
到此這篇關于C#實現(xiàn)WebAPI接口安全加密的具體方案的文章就介紹到這了,更多相關C# WebAPI接口加密內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C# SynchronizationContext以及Send和Post使用解讀
這篇文章主要介紹了C# SynchronizationContext以及Send和Post使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
C#操作Access數(shù)據(jù)庫的實現(xiàn)過程(vs2019)
這篇文章主要介紹了C#操作Access數(shù)據(jù)庫的實現(xiàn)過程(vs2019),打開Office Access新建一個空白數(shù)據(jù)庫DATA.accdb,并改好存放位置,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-02-02

