Windows 8 提供完整的密碼編譯 API (Windows.Security.Cryptography),支援非對稱加密 (RSA)、數位簽章驗證,以及 CryptographicBuffer 這個強大的資料格式轉換輔助類。本文透過完整範例示範 RSA 加密/解密、簽名/驗證、以及字串、十六進位、Base64、二進位資料間的相互轉換。
RSA 適用於加密少量資料 (如對稱金鑰)。支援多種填充模式:RSA_PKCS1、RSA_OAEP_SHA1、RSA_OAEP_SHA256、RSA_OAEP_SHA384、RSA_OAEP_SHA512。原文長度受限於金鑰長度與填充模式 (例如 2048-bit 金鑰下 OAEP SHA256 最大原文 256 位元組)。
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 Asymmetric : Page
{
public Asymmetric()
{
this.InitializeComponent();
}
private void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "i am webabcd";
uint keySize = 2048;
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "keySize: " + keySize / 8;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
string[] algorithmNames = { "RSA_PKCS1", "RSA_OAEP_SHA1", "RSA_OAEP_SHA256", "RSA_OAEP_SHA384", "RSA_OAEP_SHA512" };
foreach (var algorithmName in algorithmNames)
{
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer encrypted;
IBuffer decrypted;
IBuffer blobPublicKey;
IBuffer blobKeyPair;
CryptographicKey keyPair;
AsymmetricKeyAlgorithmProvider asymmetricAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
try
{
keyPair = asymmetricAlgorithm.CreateKeyPair(keySize);
}
catch (Exception ex)
{
lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
return;
}
encrypted = CryptographicEngine.Encrypt(keyPair, buffer, null);
lblMsg.Text += algorithmName + " encrypted: " + CryptographicBuffer.EncodeToHexString(encrypted) + " (" + encrypted.Length + ")";
lblMsg.Text += Environment.NewLine;
blobPublicKey = keyPair.ExportPublicKey();
blobKeyPair = keyPair.Export();
CryptographicKey publicKey = asymmetricAlgorithm.ImportPublicKey(blobPublicKey);
CryptographicKey keyPair2 = asymmetricAlgorithm.ImportKeyPair(blobKeyPair);
decrypted = CryptographicEngine.Decrypt(keyPair2, encrypted, null);
lblMsg.Text += algorithmName + " decrypted: " + CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decrypted);
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
}
}
}
}
使用私鑰對資料簽名,公開金鑰驗證簽名。支援 RSASIGN_PKCS1_SHA1/256/384/512 與 RSASIGN_PSS_SHA1/256/384/512 共 8 種演算法。流程:建立金鑰對 -> CryptographicEngine.Sign 簽名 -> 匯出公鑰 -> CryptographicEngine.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 Sign : Page
{
public Sign()
{
this.InitializeComponent();
}
private void btnDemo_Click(object sender, RoutedEventArgs e)
{
string plainText = "i am webabcd";
uint keySize = 2048;
lblMsg.Text = "原文: " + plainText;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "keySize: " + keySize / 8;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
string[] algorithmNames = { "RSASIGN_PKCS1_SHA1", "RSASIGN_PKCS1_SHA256", "RSASIGN_PKCS1_SHA384", "RSASIGN_PKCS1_SHA512", "RSASIGN_PSS_SHA1", "RSASIGN_PSS_SHA256", "RSASIGN_PSS_SHA384", "RSASIGN_PSS_SHA512" };
foreach (var algorithmName in algorithmNames)
{
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer blobPublicKey;
IBuffer blobKeyPair;
CryptographicKey keyPair;
AsymmetricKeyAlgorithmProvider asymmetricAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
try
{
keyPair = asymmetricAlgorithm.CreateKeyPair(keySize);
}
catch (Exception ex)
{
lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
return;
}
IBuffer signature = CryptographicEngine.Sign(keyPair, buffer);
lblMsg.Text += algorithmName + " - 原文已被簽名,簽名後的資料: " + CryptographicBuffer.EncodeToHexString(signature);
lblMsg.Text += Environment.NewLine;
blobPublicKey = keyPair.ExportPublicKey();
blobKeyPair = keyPair.Export();
CryptographicKey publicKey = asymmetricAlgorithm.ImportPublicKey(blobPublicKey);
bool isAuthenticated = CryptographicEngine.VerifySignature(publicKey, buffer, signature);
lblMsg.Text += "簽名驗證的結果: " + isAuthenticated;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += Environment.NewLine;
}
}
}
}
CryptographicBuffer 提供靜態方法實現以下轉換:
ConvertStringToBinary / ConvertBinaryToString),支援 UTF-8、UTF-16LE、UTF-16BE。CopyToByteArray / CreateFromByteArray)。DecodeFromBase64String / EncodeToBase64String)。DecodeFromHexString / EncodeToHexString)。GenerateRandomNumber / GenerateRandom)。Compare)。// 將 IBuffer 轉為 string string CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding encoding, IBuffer buffer); // 將 string 轉為 IBuffer IBuffer CryptographicBuffer.ConvertStringToBinary(string value, BinaryStringEncoding encoding); // IBuffer 複製到 byte[] void CryptographicBuffer.CopyToByteArray(IBuffer buffer, out byte[] value); // byte[] 建立 IBuffer IBuffer CryptographicBuffer.CreateFromByteArray(byte[] value); // Base64 字串解碼為 IBuffer IBuffer CryptographicBuffer.DecodeFromBase64String(string value); // Hex 字串解碼為 IBuffer IBuffer CryptographicBuffer.DecodeFromHexString(string value); // IBuffer 編碼為 Base64 字串 string CryptographicBuffer.EncodeToBase64String(IBuffer buffer); // IBuffer 編碼為 Hex 字串 string CryptographicBuffer.EncodeToHexString(IBuffer buffer); // 產生隨機 uint uint CryptographicBuffer.GenerateRandomNumber(); // 產生指定長度隨機 IBuffer IBuffer CryptographicBuffer.GenerateRandom(uint length); // 比較兩個 IBuffer bool CryptographicBuffer.Compare(IBuffer object1, IBuffer object2);
CryptographicBuffer 是密碼編譯開發中的核心輔助類,掌握其轉換方法能大幅簡化編碼/解碼程式碼。