图解使用Win8Api进行Metro风格的程序开发十三----加解密
我们紧接着上篇,这篇将介绍如何使用Cryptography WinRT API,来实现
加解密.
本篇将介绍如下9个方面:
a)CryptographicBuffer类来转换和编码字符串
b)HashAlgorithmProvider 类 支持哈希算法
c)MacAlgorithmProvider 类 支持HMAC算法
d)KeyDerivationAlgorithmProvider类 支持对称算法
e)SymmetricKeyAlgorithmProvider类 支持对称算法
f)EncryptedAndAuthenticatedData类 支持认证加密算法
g)AsymmetricKeyAlgorithmProvider类 支持非对称算法
h)AsymmetricKeyAlgorithmProvider类 支持签名算法
i)DataProtectionProvider类
我们的创建的步骤如下:
1)为了组织文件方便,我们先建一个文件夹CryptoWinRT
2)向文件夹中添加如下文件:
CryptographicBufferTest.xaml,HashAlgorithms.xaml,
HmacAlgorithms.xaml,KeyDerivation.xaml,
CipherAlgorithms.xaml,AuthenticatedEncryptionAlgorithms.xaml,
EncryptAndDecrypt.xaml,SignAndVerifySignature.xaml,
AsynchronousDataProtection.xaml,AsynchronousDataProtectionWithStreams.xaml,
创建方法请参照前一篇.
3)此时的解决方案结构如下:
4)向我们的DataSource添加导航所需要的信息
修改我们的SampleDataSource.cs文件中的SampleDataSource类中的代码,
代码如下:
public SampleDataSource() { #region Group1 var group1 = new SampleDataGroup("FilePicker", "Use Windows.Storage.Pickers API", "Access and save files using the file picker", "Assets/FilePicker.jpg", ""); group1.Items.Add(new SampleDataItem("FilePicker-PickASinglePhoto", "Pick a single photo", "only one file can selected,file type is jpg,jpeg,png", "Assets/FilePicker.jpg", "only one file can selected ", "", group1, typeof(PickASinglePhoto))); group1.Items.Add(new SampleDataItem("FilePicker-PickMultipleFiles", "Pick multiple files", "you can pick multiple files", "Assets/FilePicker.jpg", "pick multiple files", "", group1, typeof(PickMultipleFiles))); group1.Items.Add(new SampleDataItem("FilePicker-PickAFolder", "Pick a folder", "you can pick a folder", "Assets/FilePicker.jpg", "Pick a folder", "", group1, typeof(PickAFolder))); group1.Items.Add(new SampleDataItem("FilePicker-SaveAFile", "Save a file", "you can save a file", "Assets/FilePicker.jpg", "Save a file", "", group1, typeof(SaveAFile))); this.AllGroups.Add(group1); #endregion #region Group2 var group2 = new SampleDataGroup("FileAceess", "Using Windows.Storage API", "File access", "Assets/FileAccess.jpg", ""); group2.Items.Add(new SampleDataItem("FileAceess-CreatingAFile", "Create a file", "Using CreateFileAsync Create a file", "Assets/FileAccess.jpg", "Using CreateFileAsync", "", group2, typeof(CreatingAFile))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingText", "Write And Read A Text", "Using WriteTextAsync,ReadTextAsync Write And Read Text", "Assets/FileAccess.jpg", "Using WriteTextAsync,ReadTextAsync", "", group2, typeof(WritingAndReadingText))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingBytes", "Writing and reading bytes in a file", "Using WriteBufferAsync,ReadBufferAsync Write And Read bytes", "Assets/FileAccess.jpg", "Using WriteBufferAsync,ReadBufferAsync", "", group2, typeof(WritingAndReadingBytes))); group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingUsingStream", "Writing and reading using a stream", "Using OpenAsync Writing and reading using a stream", "Assets/FileAccess.jpg", "Using OpenAsync", "", group2, typeof(WritingAndReadingUsingStream))); group2.Items.Add(new SampleDataItem("FileAceess-DisplayingFileProperties", "Displaying file properties", "Using GetBasicPropertiesAsync Get File Properties", "Assets/FileAccess.jpg", "Using GetBasicPropertiesAsync", "", group2, typeof(DisplayingFileProperties))); group2.Items.Add(new SampleDataItem("FileAceess-PersistingAccess", "Persisting access to a storage item for future use", "Using MostRecentlyUsedList", "Assets/FileAccess.jpg", "Using MostRecentlyUsedList", "", group2, typeof(PersistingAccess))); group2.Items.Add(new SampleDataItem("FileAceess-CopyAFile", "Copy a file", "Using CopyAsync Copy a file", "Assets/FileAccess.jpg", "Using CopyAsync", "", group2, typeof(CopyAFile))); group2.Items.Add(new SampleDataItem("FileAceess-DeleteAFile", "Delete a file", "Using DeleteAsync Delete a file", "Assets/FileAccess.jpg", "Using DeleteAsync", "", group2, typeof(DeleteAFile))); this.AllGroups.Add(group2); #endregion #region Group3 var group3 = new SampleDataGroup("AccountPictureName", "Use Windows.System.UserProfile API", "Account Picture Name", "Assets/AccountPictureName.jpg", ""); group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserDisplayName", "Get User DisplayName", "Use UserInformation.GetDisplayNameAsync Get User DisplayName", "Assets/AccountPictureName.jpg", "Use UserInformation.GetDisplayNameAsync", "", group3, typeof(GetUserDisplayName))); group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserFirstLastName", "Get First Last Name", "Use UserInformation.GetFirstNameAsync,GetLastNameAsync Get First Name", "Assets/AccountPictureName.jpg", "Use UserInformation.GetFirstNameAsync ", "", group3, typeof(GetUserFirstLastName))); group3.Items.Add(new SampleDataItem("AccountPictureName-GetAccountPicture", "Get Account Picture", "Use UserInformation.GetAccountPicture Get Account Picture", "Assets/AccountPictureName.jpg", "Use UserInformation.GetAccountPicture", "", group3, typeof(GetAccountPicture))); group3.Items.Add(new SampleDataItem("AccountPictureName-SetAccountPictureAndListen", "Set AccountPicture And Listen", "Use UserInformation.SetAccountPicturesAsync Set AccountPicture", "Assets/AccountPictureName.jpg", "Use UserInformation.SetAccountPicturesAsync", "", group3, typeof(SetAccountPictureAndListen))); this.AllGroups.Add(group3); #endregion #region Group4 var group4 = new SampleDataGroup("ApplicationSettings", "ApplicationSettings", " Use the Windows.UI.ApplicationSettings namespace and WinJS.UI.SettingsFlyout", "Assets/ApplicationSettings.jpg", ""); group4.Items.Add(new SampleDataItem("ApplicationSettings-Default", "Default behavior with no settings integration", "Default behavior ", "Assets/ApplicationSettings.jpg", "Default behavior with no settings integration", "", group4, typeof(Default))); group4.Items.Add(new SampleDataItem("ApplicationSettings-AddSettings", "Add settings commands to the settings charm", "Add settings", "Assets/ApplicationSettings.jpg", "Add settings commands to the settings charm ", "", group4, typeof(AddSettings))); this.AllGroups.Add(group4); #endregion #region Group5 var Group5 = new SampleDataGroup("AssociationLaunching", "Use Windows.System.Launcher API", "Association Launching", "Assets/AssociationLaunching.jpg", ""); Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchFile", "Launching a file", "Use Windows.System.Launcher.LaunchFileAsync", "Assets/AssociationLaunching.jpg", "Use Windows.System.Launcher.LaunchFileAsync", "", Group5, typeof(LaunchFile))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchUri", "Launching a URI", "Use Windows.System.Launcher.LaunchUriAsync", "Assets/AssociationLaunching.jpg", "Use Windows.System.Launcher.LaunchUriAsync", "", Group5, typeof(LaunchUri))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveFile", "Receiving a file", "Receiving a file", "Assets/AssociationLaunching.jpg", "Receiving a file", "", Group5, typeof(ReceiveFile))); Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveUri", "Receiving a URI", "Receiving a URI", "Assets/AssociationLaunching.jpg", "Receiving a URI", "", Group5, typeof(ReceiveUri))); this.AllGroups.Add(Group5); #endregion #region Group6 var Group6 = new SampleDataGroup("BackgroundTransfer", "Use Windows.Networking.BackgroundTransfer API", "BackgroundDownloader And BackgroundUploader", "Assets/BackgroundTransfer.jpg", ""); Group6.Items.Add(new SampleDataItem("BackgroundTransfer-DownloadFile", "Download Files", "Use BackgroundDownloader", "Assets/BackgroundTransfer.jpg", "BackgroundDownloader", "", Group6, typeof(DownloadFile))); Group6.Items.Add(new SampleDataItem("BackgroundTransfer-UploadFile", "Upload Files", "Use BackgroundUploader", "Assets/BackgroundTransfer.jpg", "BackgroundUploader", "", Group6, typeof(UploadFile))); this.AllGroups.Add(Group6); #endregion #region Group7 var Group7 = new SampleDataGroup("Clipboard", "Use Windows.ApplicationModel.DataTransfer API", "ClipboardOperation", "Assets/Clipboard.jpg", ""); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteText", "Copy and paste text", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteText))); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteImage", "Copy and paste an image", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteImage))); Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteFile", "Copy and paste files", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(CopyAndPasteFile))); Group7.Items.Add(new SampleDataItem("Clipboard-OtherClipboardOperation", "Other Clipboard operations", "Use Clipboard.GetContent,Clipboard.SetContent", "Assets/Clipboard.jpg", "Clipboard.GetContent,Clipboard.SetContent", "", Group7, typeof(OtherClipboardOperation))); this.AllGroups.Add(Group7); #endregion #region Group8 var Group8 = new SampleDataGroup("Compression", "Use Windows.Storage.Compression API", "Compression And Decompression", "Assets/Compression.jpg", ""); Group8.Items.Add(new SampleDataItem("Compression-CompressionAndDecompression", "Compression And Decompression", "Use Windows.Storage.Compression API", "Assets/Compression.jpg", "Compression And Decompression", "", Group8, typeof(CompressionAndDecompression))); this.AllGroups.Add(Group8); #endregion #region Group9 var Group9 = new SampleDataGroup("MediaButtons", "Use Windows.Media API", "Media Buttons", "Assets/MediaButtons.jpg", ""); Group9.Items.Add(new SampleDataItem("MediaButtons-MediaEvents", "Media Events", "Use Windows.Media API", "Assets/MediaButtons.jpg", "Listening to hardware media transport events", "", Group9, typeof(MediaEvents))); this.AllGroups.Add(Group9); #endregion #region Group10 var Group10 = new SampleDataGroup("ContactPicker", "Use Windows.ApplicationModel.Contacts API", "Contact Picker", "Assets/ContactPicker.jpg", ""); Group10.Items.Add(new SampleDataItem("ContactPicker-SinglePicker", "Pick a single contact", "Use ContactPicker.PickSingleContactAsync()", "Assets/ContactPicker.jpg", "PickSingleContactAsync", "", Group10, typeof(SinglePicker))); Group10.Items.Add(new SampleDataItem("ContactPicker-MultiplePicker", "Pick multiple contacts", "Use ContactPicker.PickMultipleContactsAsync()", "Assets/ContactPicker.jpg", "PickMultipleContactsAsync", "", Group10, typeof(MultiplePicker))); this.AllGroups.Add(Group10); #endregion #region Group11 var Group11 = new SampleDataGroup("ContextMenu", "Use Windows.UI.Popups API", "Context Menu", "Assets/ContextMenu.jpg", ""); Group11.Items.Add(new SampleDataItem("ContextMenu-ShowAContextMenu", "Show a context menu", "Show a context menu", "Assets/ContextMenu.jpg", "Show a context menu", "", Group11, typeof(ShowAContextMenu))); Group11.Items.Add(new SampleDataItem("ContextMenu-ReplaceADefaultContextMenu", "Replace a default context menu", "Replace a default context menu", "Assets/ContextMenu.jpg", "Replace a default context menu", "", Group11, typeof(ReplaceADefaultContextMenu))); this.AllGroups.Add(Group11); #endregion #region Group12 var Group12 = new SampleDataGroup("CryptoWinRT", "Use Cryptography WinRT API", "CryptoWinRT", "Assets/CryptoWinRT.jpg", ""); Group12.Items.Add(new SampleDataItem("CryptoWinRT-CryptographicBuffer", "CryptographicBuffer", "CryptographicBuffer", "Assets/CryptoWinRT.jpg", "CryptographicBuffer", "", Group12, typeof(CryptographicBufferTest))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-HashAlgorithms", "HashAlgorithms", "HashAlgorithms", "Assets/CryptoWinRT.jpg", "HashAlgorithms", "", Group12, typeof(HashAlgorithms))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-HmacAlgorithms", "HmacAlgorithms", "HmacAlgorithms", "Assets/CryptoWinRT.jpg", "HmacAlgorithms", "", Group12, typeof(HmacAlgorithms))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-KeyDerivation", "KeyDerivation", "KeyDerivation", "Assets/CryptoWinRT.jpg", "KeyDerivation", "", Group12, typeof(KeyDerivation))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-CipherAlgorithms", "CipherAlgorithms", "CipherAlgorithms", "Assets/CryptoWinRT.jpg", "CipherAlgorithms", "", Group12, typeof(CipherAlgorithms))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-AuthenticatedEncryptionAlgorithms", "AuthenticatedEncryptionAlgorithms", "AuthenticatedEncryptionAlgorithms", "Assets/CryptoWinRT.jpg", "AuthenticatedEncryptionAlgorithms", "", Group12, typeof(AuthenticatedEncryptionAlgorithms))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-EncryptAndDecrypt", "EncryptAndDecrypt", "EncryptAndDecrypt", "Assets/CryptoWinRT.jpg", "EncryptAndDecrypt", "", Group12, typeof(EncryptAndDecrypt))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-SignAndVerifySignature", "SignAndVerifySignature", "SignAndVerifySignature", "Assets/CryptoWinRT.jpg", "SignAndVerifySignature", "", Group12, typeof(SignAndVerifySignature))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-AsynchronousDataProtection", "AsynchronousDataProtection", "AsynchronousDataProtection", "Assets/CryptoWinRT.jpg", "AsynchronousDataProtection", "", Group12, typeof(AsynchronousDataProtection))); Group12.Items.Add(new SampleDataItem("CryptoWinRT-AsynchronousDataProtectionWithStreams", "AsynchronousDataProtectionWithStreams", "AsynchronousDataProtectionWithStreams", "Assets/CryptoWinRT.jpg", "AsynchronousDataProtectionWithStreams", "", Group12, typeof(AsynchronousDataProtectionWithStreams))); this.AllGroups.Add(Group12); #endregion }
5)我们的导航这样就做好了,效果图:
点击 CryptoWinRT
6)使用CryptographicBuffer类来转换和编码字符串
修改CryptographicBufferTest的xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="InputTextBlock1" TextWrapping="Wrap" Grid.Row="0" Style="{StaticResource BodyTextStyle}" HorizontalAlignment="Left" > CryptographicBuffer - the use of the CryptographicBuffer class in WinRT. </TextBlock> <StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1"> <Button Name="RunSample" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class CryptographicBufferTest : Page { public CryptographicBufferTest() { this.InitializeComponent(); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { IBuffer buffer; OutputText.Text = ""; byte[] ByteArray = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; String base64String = "UmVmYWN0b3I="; String hexString = "19891026"; String inputString = "Refactor"; //创建包含随机数据的缓冲区 buffer = CryptographicBuffer.GenerateRandom(32); OutputText.Text += "GenerateRandom\n"; //将缓冲区编码为十六进制字符串 OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; // 从输入字节数组创建缓冲区 buffer = CryptographicBuffer.CreateFromByteArray(ByteArray); OutputText.Text += "CreateFromByteArray\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; // 对 Base64 编码进行解码 buffer = CryptographicBuffer.DecodeFromBase64String(base64String); OutputText.Text += "DecodeFromBase64String\n"; OutputText.Text += " Base64 String: " + base64String + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; // 对十六进制编码的字符串进行解码 buffer = CryptographicBuffer.DecodeFromHexString(hexString); OutputText.Text += "DecodeFromHexString\n"; OutputText.Text += " Hex String: " + hexString + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; // 将字符串转换为已编码的缓冲区 buffer = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf16BE); OutputText.Text += "ConvertStringToBinary (Utf16BE)\n"; OutputText.Text += " String: " + inputString + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; buffer = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf16LE); OutputText.Text += "ConvertStringToBinary (Utf16LE)\n"; OutputText.Text += " String: " + inputString + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; buffer = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf8); OutputText.Text += "ConvertStringToBinary (Utf8)\n"; OutputText.Text += " String: " + inputString + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; buffer = CryptographicBuffer.DecodeFromBase64String(base64String); OutputText.Text += "DecodeFromBase64String \n"; OutputText.Text += " String: " + base64String + "\n"; OutputText.Text += " Buffer (Hex): " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; OutputText.Text += " Buffer (Base64): " + CryptographicBuffer.EncodeToBase64String(buffer) + "\n\n"; buffer = CryptographicBuffer.DecodeFromHexString(hexString); OutputText.Text += "DecodeFromHexString \n"; OutputText.Text += " String: " + hexString + "\n"; OutputText.Text += " Buffer: " + CryptographicBuffer.EncodeToHexString(buffer) + "\n\n"; } }
7)使用HashAlgorithmProvider 类 支持哈希算法
修改HashAlgorithms.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Text="Hash Algorithms - how to use the Hash algorithms that are included in WinRT for the various suported hashing algorithms." Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left"/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200"> <ComboBoxItem> <x:String>MD5</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SHA512</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class HashAlgorithms : Page { public HashAlgorithms() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { OutputText.Text = ""; String inputString = "Refactor"; String algName = AlgorithmNames.SelectionBoxItem.ToString(); // 加密哈希算法提供程序 HashAlgorithmProvider Algorithm = HashAlgorithmProvider.OpenAlgorithm(algName); IBuffer vector = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf8); OutputText.Text += "\n*** Sample Hash Algorithm: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Initial string: Refactor\n"; // 哈希二进制数据 IBuffer digest = Algorithm.HashData(vector); if (digest.Length != Algorithm.HashLength) { OutputText.Text += "HashAlgorithmProvider failed to generate a hash of proper length!\n"; return; } //将缓冲区编码为16进制字符串 OutputText.Text += " Hash: " + CryptographicBuffer.EncodeToHexString(digest) + "\n"; CryptographicHash reusableHash = Algorithm.CreateHash(); reusableHash.Append(vector); IBuffer digest2 = reusableHash.GetValueAndReset(); if (!CryptographicBuffer.Compare(digest, digest2)) { OutputText.Text += "CryptographicHash failed to generate the same hash data!\n"; return; } reusableHash.Append(vector); digest2 = reusableHash.GetValueAndReset(); if (!CryptographicBuffer.Compare(digest, digest2)) { OutputText.Text += "Reusable CryptographicHash failed to generate the same hash data!\n"; return; } } }
8)使用MacAlgorithmProvider 类 支持HMAC算法
修改HmacAlgorithms.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Text="Hmac Algorithms - how to use the HMAC algorithms to sign and verify data using the WinRT APIs." Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left"/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200"> <ComboBoxItem> <x:String>HMAC_MD5</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>HMAC_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>HMAC_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>HMAC_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>HMAC_SHA512</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class HmacAlgorithms : Page { public HmacAlgorithms() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); OutputText.Text = ""; String Message = "Refactor"; MacAlgorithmProvider Algorithm = MacAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "*** Sample Hmac Algorithm: " + Algorithm.AlgorithmName + "\n"; IBuffer keymaterial = CryptographicBuffer.GenerateRandom(Algorithm.MacLength); //创建key CryptographicKey hmacKey = Algorithm.CreateKey(keymaterial); // 对加密解密进行签名 IBuffer signature = CryptographicEngine.Sign( hmacKey, CryptographicBuffer.ConvertStringToBinary(Message, BinaryStringEncoding.Utf8) ); OutputText.Text += " Signature: " + CryptographicBuffer.EncodeToHexString(signature) + "\n"; hmacKey = Algorithm.CreateKey(keymaterial); bool IsAuthenticated = Windows.Security.Cryptography.Core.CryptographicEngine.VerifySignature( hmacKey, CryptographicBuffer.ConvertStringToBinary(Message, BinaryStringEncoding.Utf8), signature ); if (!IsAuthenticated) { OutputText.Text += "HashAlgorithmProvider failed to generate a hash of proper length!\n"; return; } } }
9)使用KeyDerivationAlgorithmProvider类 支持对称算法
修改KeyDerivation.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BasicTextStyle}" Text="Key Derivation - how to derive Keys for various Algorithms and Key Sizes using the WinRT APIs."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="250" Margin="5,5,5,5"> <ComboBoxItem> <x:String>PBKDF2_MD5</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>PBKDF2_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>PBKDF2_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SP800_108_CTR_HMAC_MD5</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SP800_108_CTR_HMAC_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SP800_108_CTR_HMAC_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SP800_56A_CONCAT_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>SP800_56A_CONCAT_SHA512</x:String> </ComboBoxItem> </ComboBox> <ComboBox Name="KeySizes" Width="100" Margin="5,5,5,5"> <ComboBoxItem> <x:String>64</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>256</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class KeyDerivation : Page { public KeyDerivation() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; KeySizes.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); IBuffer Secret = CryptographicBuffer.ConvertStringToBinary("Refactor", BinaryStringEncoding.Utf8); UInt32 TargetSize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); OutputText.Text = ""; //派生密钥时使用的参数 KeyDerivationParameters Params; if (algName.Contains("PBKDF2")) { Params = KeyDerivationParameters.BuildForPbkdf2( CryptographicBuffer.GenerateRandom(16), 10000 ); } else if (algName.Contains("SP800_108")) { Params = KeyDerivationParameters.BuildForSP800108( CryptographicBuffer.ConvertStringToBinary("Refactor", BinaryStringEncoding.Utf8), CryptographicBuffer.DecodeFromHexString("19891026") ); } else if (algName.Contains("SP800_56A")) { Params = KeyDerivationParameters.BuildForSP80056a( CryptographicBuffer.ConvertStringToBinary("Refactor", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("Refactor1", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("Refactor2", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("Refactor3", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("Refactor4", BinaryStringEncoding.Utf8) ); } else { OutputText.Text += " An invalid algorithm was specified.\n"; return; } // Create a KeyDerivationAlgorithmProvider object for the algorithm specified on input. KeyDerivationAlgorithmProvider Algorithm = KeyDerivationAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "*** Sample Kdf Algorithm: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Secrect Size: " + Secret.Length + "\n"; OutputText.Text += " Target Size: " + TargetSize + "\n"; // Create a key. CryptographicKey key = Algorithm.CreateKey(Secret); // Derive a key from the created key. IBuffer derived = CryptographicEngine.DeriveKeyMaterial(key, Params, TargetSize); OutputText.Text += " Derived " + derived.Length + " bytes\n"; OutputText.Text += " Derived: " + CryptographicBuffer.EncodeToHexString(derived) + "\n"; } }
10)使用SymmetricKeyAlgorithmProvider类 支持对称算法
修改CipherAlgorithms.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Cipher Algorithms - how generate symmetric keys and use them for encryption and decryption using the WinRT APIs."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200" Margin="5,5,5,5"> <ComboBoxItem> <x:String>AES_CBC</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>AES_ECB</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>AES_CBC_PKCS7</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>AES_ECB_PKCS7</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>DES_CBC</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>DES_ECB</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>3DES_CBC</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>3DES_ECB</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>3DES_CBC_PKCS7</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>3DES_ECB_PKCS7</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RC2_CBC</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RC2_ECB</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RC4</x:String> </ComboBoxItem> </ComboBox> <ComboBox Name="KeySizes" Width="100" Margin="5,5,5,5"> <ComboBoxItem> <x:String>64</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>128</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>192</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>512</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class CipherAlgorithms : Page { public CipherAlgorithms() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; KeySizes.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); UInt32 keySize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); OutputText.Text = ""; IBuffer encrypted; IBuffer decrypted; IBuffer buffer; IBuffer iv = null; String blockCookie = "1234567812345678"; // 16 bytes // 对称密钥提供程序 SymmetricKeyAlgorithmProvider Algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "\n*** Sample Cipher Encryption\n"; OutputText.Text += " Algorithm Name: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Key Size: " + keySize + "\n"; OutputText.Text += " Block length: " + Algorithm.BlockLength + "\n"; IBuffer keymaterial = CryptographicBuffer.GenerateRandom((keySize + 7) / 8); CryptographicKey key; try { //创建对称键 key = Algorithm.CreateSymmetricKey(keymaterial); } catch (ArgumentException ex) { OutputText.Text += ex.Message + "\n"; OutputText.Text += "An invalid key size was selected for the given algorithm.\n"; return; } if (algName.Contains("CBC")) iv = CryptographicBuffer.GenerateRandom(Algorithm.BlockLength); buffer = CryptographicBuffer.ConvertStringToBinary(blockCookie, BinaryStringEncoding.Utf8); encrypted = CryptographicEngine.Encrypt(key, buffer, iv); OutputText.Text += " Plain text: " + buffer.Length + " bytes\n"; OutputText.Text += " Encrypted: " + encrypted.Length + " bytes\n"; CryptographicKey key2 = Algorithm.CreateSymmetricKey(keymaterial); if (key.KeySize != key2.KeySize) { OutputText.Text += "CreateSymmetricKey failed! The imported key's size did not match the original's!"; return; } decrypted =CryptographicEngine.Decrypt(key2, encrypted, iv); if (!CryptographicBuffer.Compare(decrypted, buffer)) { OutputText.Text += "Decrypted does not match original!"; return; } } }
11)使用EncryptedAndAuthenticatedData类 支持认证加密算法
修改AuthenticatedEncryptionAlgorithms.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Authenticated Encryption Algorithms -how to perform Authenticated Encryption and Decryption with the WinRT APIs."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200" Margin="5,5,5,5"> <ComboBoxItem> <x:String>AES_GCM</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>AES_CCM</x:String> </ComboBoxItem> </ComboBox> <ComboBox Name="KeySizes" Width="100" Margin="5,5,5,5"> <ComboBoxItem> <x:String>128</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>256</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class AuthenticatedEncryptionAlgorithms : Page { static byte[] NonceBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; public AuthenticatedEncryptionAlgorithms() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; KeySizes.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } IBuffer GetNonce() { NonceBytes[0]++; for (int i = 0; i < NonceBytes.Length - 1; i++) { if (NonceBytes[i] == 255) { NonceBytes[i + 1]++; } } return CryptographicBuffer.CreateFromByteArray(NonceBytes); } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); UInt32 keySize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); OutputText.Text = ""; IBuffer Decrypted; IBuffer Data; IBuffer Nonce; String Cookie = "Refactor"; Data = CryptographicBuffer.ConvertStringToBinary(Cookie, BinaryStringEncoding.Utf16LE); SymmetricKeyAlgorithmProvider Algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "*** Sample Authenticated Encryption\n"; OutputText.Text += " Algorithm Name: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Key Size: " + keySize + "\n"; OutputText.Text += " Block length: " + Algorithm.BlockLength + "\n"; IBuffer keymaterial = CryptographicBuffer.GenerateRandom((keySize + 7) / 8); CryptographicKey key = Algorithm.CreateSymmetricKey(keymaterial); Nonce = GetNonce(); EncryptedAndAuthenticatedData Encrypted = CryptographicEngine.EncryptAndAuthenticate(key, Data, Nonce, null); OutputText.Text += " Plain text: " + Data.Length + " bytes\n"; OutputText.Text += " Encrypted: " + Encrypted.EncryptedData.Length + " bytes\n"; OutputText.Text += " AuthTag: " + Encrypted.AuthenticationTag.Length + " bytes\n"; CryptographicKey key2 = Algorithm.CreateSymmetricKey(keymaterial); if (key.KeySize != key2.KeySize) { OutputText.Text += "CreateSymmetricKey failed! The imported key's size did not match the original's!"; return; } Decrypted = CryptographicEngine.DecryptAndAuthenticate(key2, Encrypted.EncryptedData, Nonce, Encrypted.AuthenticationTag, null); if (!CryptographicBuffer.Compare(Decrypted, Data)) { OutputText.Text += "Decrypted does not match original!"; return; } } }
12)使用AsymmetricKeyAlgorithmProvider类 支持非对称算法
修改EncryptAndDecrypt.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Encrypt and Decrypt - how to Encrypt and Decrypt data with the WinRT APIs for supported Algorithms and Key Sizes."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200" Margin="5,5,5,5"> <ComboBoxItem> <x:String>RSA_PKCS1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSA_OAEP_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSA_OAEP_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSA_OAEP_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSA_OAEP_SHA512</x:String> </ComboBoxItem> </ComboBox> <ComboBox Name="KeySizes" Width="100" Margin="5,5,5,5"> <ComboBoxItem> <x:String>512</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>1024</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>2048</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>4096</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class EncryptAndDecrypt : Page { public EncryptAndDecrypt() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; KeySizes.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); UInt32 KeySize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); OutputText.Text = ""; IBuffer Data; String cookie = "Refactor"; switch (AlgorithmNames.SelectedIndex) { case 0: Data = CryptographicBuffer.ConvertStringToBinary(cookie, BinaryStringEncoding.Utf16LE); break; case 1: Data = CryptographicBuffer.GenerateRandom(1024 / 8 - 2 * 20 - 2); break; case 2: Data = CryptographicBuffer.GenerateRandom(1024 / 8 - 2 * (256 / 8) - 2); break; case 3: Data = CryptographicBuffer.GenerateRandom(2048 / 8 - 2 * (384 / 8) - 2); break; case 4: Data = CryptographicBuffer.GenerateRandom(2048 / 8 - 2 * (512 / 8) - 2); break; default: OutputText.Text += "An invalid algorithm was selected"; return; } IBuffer Encrypted; IBuffer Decrypted; IBuffer blobOfPublicKey; IBuffer blobOfKeyPair; AsymmetricKeyAlgorithmProvider Algorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "*** Sample Encryption Algorithm\n"; OutputText.Text += " Algorithm Name: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Key Size: " + KeySize + "\n"; CryptographicKey keyPair = Algorithm.CreateKeyPair(KeySize); try { Encrypted = CryptographicEngine.Encrypt(keyPair, Data, null); } catch (ArgumentException ex) { OutputText.Text += ex.Message + "\n"; OutputText.Text += "An invalid key size was selected for the given algorithm.\n"; return; } OutputText.Text += " Plain text: " + Data.Length + " bytes\n"; OutputText.Text += " Encrypted: " + Encrypted.Length + " bytes\n"; blobOfPublicKey = keyPair.ExportPublicKey(); blobOfKeyPair = keyPair.Export(); CryptographicKey keyPublic = Algorithm.ImportPublicKey(blobOfPublicKey); if (keyPublic.KeySize != keyPair.KeySize) { OutputText.Text += "ImportPublicKey failed! The imported key's size did not match the original's!"; return; } keyPair = Algorithm.ImportKeyPair(blobOfKeyPair); // Check the key size of the imported key. if (keyPublic.KeySize != keyPair.KeySize) { OutputText.Text += "ImportKeyPair failed! The imported key's size did not match the original's!"; return; } Decrypted = CryptographicEngine.Decrypt(keyPair, Encrypted, null); if (!CryptographicBuffer.Compare(Decrypted, Data)) { OutputText.Text += "Decrypted data does not match original!"; return; } } }
13)使用AsymmetricKeyAlgorithmProvider类 支持签名算法
修改SignAndVerifySignature.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Sign and Verify Signature - how to use asymmetric keys for data signature and how to verify the signature with the WinRT APIs."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <ComboBox Name="AlgorithmNames" Width="200" Margin="5,5,5,5"> <ComboBoxItem> <x:String>ECDSA_P256_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>ECDSA_P384_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>ECDSA_P521_SHA512</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PKCS1_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PKCS1_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PKCS1_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PKCS1_SHA512</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PSS_SHA1</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PSS_SHA256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PSS_SHA384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>RSASIGN_PSS_SHA512</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>DSA_SHA1</x:String> </ComboBoxItem> </ComboBox> <ComboBox Name="KeySizes" Width="100" Margin="5,5,5,5"> <ComboBoxItem> <x:String>256</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>384</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>521</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>1024</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>2048</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>3072</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>4096</x:String> </ComboBoxItem> </ComboBox> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class SignAndVerifySignature : Page { public SignAndVerifySignature() { this.InitializeComponent(); AlgorithmNames.SelectedIndex = 0; KeySizes.SelectedIndex = 0; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void Run_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); UInt32 KeySize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); OutputText.Text = ""; CryptographicKey keyPair; IBuffer blobOfPublicKey; IBuffer blobOfKeyPair; String cookie = "Refactor"; IBuffer Data = CryptographicBuffer.ConvertStringToBinary(cookie, BinaryStringEncoding.Utf16BE); AsymmetricKeyAlgorithmProvider Algorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algName); OutputText.Text += "*** Sample Signature Algorithm\n"; OutputText.Text += " Algorithm Name: " + Algorithm.AlgorithmName + "\n"; OutputText.Text += " Key Size: " + KeySize + "\n"; try { keyPair = Algorithm.CreateKeyPair(KeySize); } catch (ArgumentException ex) { OutputText.Text += ex.Message + "\n"; OutputText.Text += "An invalid key size was specified for the given algorithm."; return; } IBuffer Signature = CryptographicEngine.Sign(keyPair, Data); OutputText.Text += " Data was successfully signed.\n"; blobOfPublicKey = keyPair.ExportPublicKey(); blobOfKeyPair = keyPair.Export(); OutputText.Text += " Key pair was successfully exported.\n"; CryptographicKey keyPublic = Algorithm.ImportPublicKey(blobOfPublicKey); if (keyPublic.KeySize != keyPair.KeySize) { OutputText.Text += "ImportPublicKey failed! The imported key's size did not match the original's!"; return; } OutputText.Text += " Public key was successfully imported.\n"; keyPair = Algorithm.ImportKeyPair(blobOfKeyPair); if (keyPublic.KeySize != keyPair.KeySize) { OutputText.Text += "ImportKeyPair failed! The imported key's size did not match the original's!"; return; } OutputText.Text += " Key pair was successfully imported.\n"; if (!CryptographicEngine.VerifySignature(keyPublic, Data, Signature)) { OutputText.Text += "Signature verification failed!"; return; } OutputText.Text += " Signature was successfully verified.\n"; } }
14)使用DataProtectionProvider类
修改AsynchronousDataProtection.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Asynchronous Data Protection -protecting and unprotecting data asynchronously using the WinRT APIs."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBox x:Name="tbDescriptor" Width="340" Text="Local=user" Margin="5,5,5,5" /> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class AsynchronousDataProtection : Page { public AsynchronousDataProtection() { this.InitializeComponent(); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } public async void SampleDataProtection(String descriptor) { OutputText.Text += "*** Sample Data Protection for " + descriptor + " ***\n"; DataProtectionProvider Provider = new DataProtectionProvider(descriptor); OutputText.Text += " DataProtectionProvider is Ready\n"; IBuffer data = CryptographicBuffer.GenerateRandom(73); OutputText.Text += " Original Data: " + CryptographicBuffer.EncodeToHexString(data) + "\n"; IBuffer protectedData = await Provider.ProtectAsync(data); OutputText.Text += " Protected Data: " + CryptographicBuffer.EncodeToHexString(protectedData) + "\n"; if (CryptographicBuffer.Compare(data, protectedData)) { OutputText.Text += "ProtectAsync returned unprotected data"; return; } OutputText.Text += " ProtectAsync succeeded\n"; DataProtectionProvider Provider2 = new DataProtectionProvider(); IBuffer unprotectedData = await Provider2.UnprotectAsync(protectedData); if (!CryptographicBuffer.Compare(data, unprotectedData)) { OutputText.Text += "UnprotectAsync returned invalid data"; return; } OutputText.Text += " Unprotected Data: " + CryptographicBuffer.EncodeToHexString(unprotectedData) + "\n"; OutputText.Text += "*** Done!\n"; } /// <summary> /// This is the click handler for the 'Default' button. You would replace this with your own handler /// if you have a button or buttons on this page. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Run_Click(object sender, RoutedEventArgs e) { String descriptor = tbDescriptor.Text; SampleDataProtection(descriptor); } }
修改AsynchronousDataProtectionWithStreams.xaml的xaml
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="Input" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel> <TextBlock TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}" Text="Asynchronous Data Protection with Streams - how to use the Data Protection Streaming APIs with memory streams."/> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBox x:Name="tbDescriptor" Width="340" Text="Local=user" Margin="5,5,5,5" /> <Button x:Name="Run" Content="Run" Margin="0,0,10,0" Click="Run_Click"/> </StackPanel> </StackPanel> </Grid> <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1"> <TextBlock Name="OutputText" TextWrapping="Wrap" Style="{StaticResource BodyTextStyle}"/> </Grid> </Grid>
修改后台代码:
public sealed partial class AsynchronousDataProtectionWithStreams : Page { public AsynchronousDataProtectionWithStreams() { this.InitializeComponent(); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } public async void SampleDataProtectionStream(String descriptor) { OutputText.Text += "*** Sample Stream Data Protection for " + descriptor + " ***\n"; IBuffer data = CryptographicBuffer.GenerateRandom(10000); DataReader reader1, reader2; IBuffer buff1, buff2; DataProtectionProvider Provider = new DataProtectionProvider(descriptor); InMemoryRandomAccessStream originalData = new InMemoryRandomAccessStream(); IOutputStream outputStream = originalData.GetOutputStreamAt(0); DataWriter writer = new DataWriter(outputStream); writer.WriteBuffer(data); await writer.StoreAsync(); await outputStream.FlushAsync(); IInputStream source = originalData.GetInputStreamAt(0); InMemoryRandomAccessStream protectedData = new InMemoryRandomAccessStream(); IOutputStream dest = protectedData.GetOutputStreamAt(0); await Provider.ProtectStreamAsync(source, dest); if (await dest.FlushAsync()) OutputText.Text += " Protected output was successfully flushed\n"; reader1 = new DataReader(originalData.GetInputStreamAt(0)); reader2 = new DataReader(protectedData.GetInputStreamAt(0)); await reader1.LoadAsync((uint)originalData.Size); await reader2.LoadAsync((uint)protectedData.Size); OutputText.Text += " Size of original stream: " + originalData.Size + "\n"; OutputText.Text += " Size of protected stream: " + protectedData.Size + "\n"; if (originalData.Size == protectedData.Size) { buff1 = reader1.ReadBuffer((uint)originalData.Size); buff2 = reader2.ReadBuffer((uint)protectedData.Size); if (CryptographicBuffer.Compare(buff1, buff2)) { OutputText.Text += "ProtectStreamAsync returned unprotected data"; return; } } OutputText.Text += " Stream Compare completed. Streams did not match.\n"; source = protectedData.GetInputStreamAt(0); InMemoryRandomAccessStream unprotectedData = new InMemoryRandomAccessStream(); dest = unprotectedData.GetOutputStreamAt(0); DataProtectionProvider Provider2 = new DataProtectionProvider(); await Provider2.UnprotectStreamAsync(source, dest); if (await dest.FlushAsync()) OutputText.Text += " Unprotected output was successfully flushed\n"; reader1 = new DataReader(originalData.GetInputStreamAt(0)); reader2 = new DataReader(unprotectedData.GetInputStreamAt(0)); await reader1.LoadAsync((uint)originalData.Size); await reader2.LoadAsync((uint)unprotectedData.Size); OutputText.Text += " Size of original stream: " + originalData.Size + "\n"; OutputText.Text += " Size of unprotected stream: " + unprotectedData.Size + "\n"; buff1 = reader1.ReadBuffer((uint)originalData.Size); buff2 = reader2.ReadBuffer((uint)unprotectedData.Size); if (!CryptographicBuffer.Compare(buff1, buff2)) { OutputText.Text += "UnrotectStreamAsync did not return expected data"; return; } OutputText.Text += "*** Done!\n"; } private void Run_Click(object sender, RoutedEventArgs e) { String descriptor = tbDescriptor.Text; SampleDataProtectionStream(descriptor); } }
未完待续,敬请期待...
转载请注明出处:http://www.cnblogs.com/refactor/