對稱加密、雜湊函數、HMAC 以及 Windows 內建的本地資料保護 (DPAPI) 是應用程式資料安全的基石。本文系統介紹 MD5/SHA 系列雜湊、HMAC 訊息驗證碼、DataProtectionProvider 使用者/機器層級加密、以及 AES/DES/3DES/RC2/RC4 等對稱演算法的完整實作範例。
支援 MD5、SHA1、SHA256、SHA384、SHA512。HashAlgorithmProvider 提供單次雜湊 (HashData) 與累加式雜湊 (CreateHash + Append + GetValueAndReset) 兩種模式。
using System;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Crypto
{
public sealed partial class Hash : Page
{
public Hash()
{
this.InitializeComponent();
}
private void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "i am webabcd";
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
string[] algorithmNames = { "MD5", "SHA1", "SHA256", "SHA384", "SHA512" };
foreach (var algorithmName in algorithmNames)
{
HashAlgorithmProvider hashAlgorithm = HashAlgorithmProvider.OpenAlgorithm(algorithmName);
IBuffer vector = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer digest = hashAlgorithm.HashData(vector);
lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(digest);
lblMsg.Text += Environment.NewLine;
CryptographicHash reusableHash = hashAlgorithm.CreateHash();
reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("i ", BinaryStringEncoding.Utf8));
reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("am ", BinaryStringEncoding.Utf8));
reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("webabcd", BinaryStringEncoding.Utf8));
digest = reusableHash.GetValueAndReset();
lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(digest);
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
}
}
}
}
HMAC = Hash + Secret Key。支援 HMAC_MD5、HMAC_SHA1、HMAC_SHA256、HMAC_SHA384、HMAC_SHA512。流程:開啟演算法提供者 -> 產生隨機金鑰 (GenerateRandom) -> CreateKey -> CryptographicEngine.Sign 產生 HMAC -> VerifySignature 驗證。
using System;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Crypto
{
public sealed partial class Hmac : Page
{
public Hmac()
{
this.InitializeComponent();
}
private void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "i am webabcd";
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
string[] algorithmNames = { "HMAC_MD5", "HMAC_SHA1", "HMAC_SHA256", "HMAC_SHA384", "HMAC_SHA512" };
foreach (var algorithmName in algorithmNames)
{
MacAlgorithmProvider hmacAlgorithm = MacAlgorithmProvider.OpenAlgorithm(algorithmName);
IBuffer key = CryptographicBuffer.GenerateRandom(hmacAlgorithm.MacLength);
CryptographicKey hmacKey = hmacAlgorithm.CreateKey(key);
IBuffer signature = CryptographicEngine.Sign(hmacKey, CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8));
lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(signature) + " (key: " + CryptographicBuffer.EncodeToHexString(key) + ")";
lblMsg.Text += Environment.NewLine;
bool isAuthenticated = CryptographicEngine.VerifySignature(hmacKey, CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8), signature);
lblMsg.Text += "isAuthenticated: " + isAuthenticated;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
}
}
}
}
DataProtectionProvider 封裝 Windows DPAPI,提供使用者層級 (Local=user) 或機器層級 (LOCAL=machine) 加密。加密後的資料僅能在相同使用者/機器環境下解密,適合儲存敏感設定、Token 等。支援緩衝區 (ProtectAsync/UnprotectAsync) 與串流 (ProtectStreamAsync/UnprotectStreamAsync) 兩種模式。
using System;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.DataProtection;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Crypto
{
public sealed partial class LocalCryptoString : Page
{
public LocalCryptoString()
{
this.InitializeComponent();
}
private async void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "i am webabcd";
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
DataProtectionProvider provider = new DataProtectionProvider("Local=user");
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer encrypted = await provider.ProtectAsync(buffer);
lblMsg.Text += "encrypted: " + CryptographicBuffer.EncodeToHexString(encrypted);
lblMsg.Text += Environment.NewLine;
DataProtectionProvider provider2 = new DataProtectionProvider();
IBuffer decrypted = await provider2.UnprotectAsync(encrypted);
lblMsg.Text += "decrypted: " + CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decrypted);
lblMsg.Text += Environment.NewLine;
}
}
}
支援 AES (CBC/ECB, PKCS7/無填充)、DES、3DES、RC2、RC4。關鍵參數:金鑰長度 (AES 128/192/256, DES 64, 3DES 192, RC2/RC4 可變)、區塊長度、初始向量 (CBC 模式必須)、填充模式 (PKCS7 或無)。SymmetricKeyAlgorithmProvider 建立金鑰,CryptographicEngine.Encrypt/Decrypt 執行加解密。
using System;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Crypto
{
public sealed partial class Symmetric : Page
{
public Symmetric()
{
this.InitializeComponent();
}
private void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "1234567812345678";
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
string[] algorithmNames = { "AES_CBC", "AES_ECB", "AES_CBC_PKCS7", "AES_ECB_PKCS7", "DES_CBC", "DES_ECB", "3DES_CBC", "3DES_ECB", "3DES_CBC_PKCS7", "3DES_ECB_PKCS7", "RC2_CBC", "RC2_ECB", "RC4" };
foreach (var algorithmName in algorithmNames)
{
uint keySize = 128;
if (algorithmName.StartsWith("AES")) keySize = 128;
else if (algorithmName.StartsWith("DES")) keySize = 64;
else if (algorithmName.StartsWith("3DES")) keySize = 192;
else if (algorithmName.StartsWith("RC2")) keySize = 128;
else if (algorithmName.StartsWith("RC4")) keySize = 128;
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer encrypted;
IBuffer decrypted;
IBuffer iv = null;
SymmetricKeyAlgorithmProvider symmetricAlgorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
IBuffer key = CryptographicBuffer.GenerateRandom(keySize / 8);
CryptographicKey cryptoKey = symmetricAlgorithm.CreateSymmetricKey(key);
if (algorithmName.Contains("CBC"))
iv = CryptographicBuffer.GenerateRandom(symmetricAlgorithm.BlockLength);
try
{
encrypted = CryptographicEngine.Encrypt(cryptoKey, buffer, iv);
}
catch (Exception ex)
{
lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
return;
}
lblMsg.Text += algorithmName + " encrypted: " + CryptographicBuffer.EncodeToHexString(encrypted);
lblMsg.Text += Environment.NewLine;
CryptographicKey cryptoKey2 = symmetricAlgorithm.CreateSymmetricKey(key);
try
{
decrypted = CryptographicEngine.Decrypt(cryptoKey2, encrypted, iv);
}
catch (Exception ex)
{
lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
return;
}
lblMsg.Text += algorithmName + " decrypted: " + CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decrypted);
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
}
}
}
}
DataProtectionProvider 是最簡單的本地敏感資料保護方式,自動綁定使用者/機器憑證。