zoukankan      html  css  js  c++  java
  • 重新想象 Windows 8 Store Apps (32) 加密解密: 非对称算法, 数据转换的辅助类

    [源码下载]


    重新想象 Windows 8 Store Apps (32) - 加密解密: 非对称算法, 数据转换的辅助类



    作者:webabcd


    介绍
    重新想象 Windows 8 Store Apps 之 加密解密

    • 非对称算法(RSA)
    • 签名和验证签名(RSA)
    • 通过 CryptographicBuffer 来实现 string hex base64 binary 间的相互转换



    示例
    1、演示如何使用非对称算法(RSA)
    Crypto/Asymmetric.xaml.cs

    /*
     * 演示如何使用非对称算法(RSA)
     */
    
    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)
                {
                    /*
                     * 对于 RSA 非对称加密来说,其对原文的长度是有限制的,所以一般用 RSA 来加密对称算法的密钥
                     * 
                     * RSA_PKCS1 要求原文长度 <= 密钥长度 - 3,单位:字节
                     * OAEP 要求原文长度 <= 密钥长度 - 2 * HashBlock - 2,单位:字节
                     *     RSA_OAEP_SHA1 - 密钥长度为 1024 时,最大原文长度 1024 / 8 - 2 * 20 - 2 = 90
                     *     RSA_OAEP_SHA256 - 密钥长度为 1024 时,最大原文长度 1024 / 8 - 2 * (256 / 8) - 2 = 66
                     *     RSA_OAEP_SHA384 - 密钥长度为 2048 时,最大原文长度 2048 / 8 - 2 * (384 / 8) - 2 = 162
                     *     RSA_OAEP_SHA512 - 密钥长度为 2048 时,最大原文长度 2048 / 8 - 2 * (512 / 8) - 2 = 130
                     */
    
                    IBuffer buffer; // 原文
                    IBuffer encrypted; // 加密后
                    IBuffer decrypted; // 解密后
                    IBuffer blobPublicKey; // 公钥
                    IBuffer blobKeyPair; // 公钥私钥对
    
                    CryptographicKey keyPair; // 公钥私钥对
    
                    // 原文的二进制数据
                    buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
    
                    // 根据算法名称实例化一个非对称算法提供程序
                    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;
                }
            }
        }
    }


    2、演示如何通过非对称算法(RSA)来签名和验证签名
    Crypto/Sign.xaml.cs

    /*
     * 演示如何通过非对称算法(RSA)来签名和验证签名
     */
    
    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; // 原文
                    IBuffer blobPublicKey; // 公钥
                    IBuffer blobKeyPair; // 公钥私钥对
    
                    CryptographicKey keyPair; // 公钥私钥对
    
                    // 原文的二进制数据
                    buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
    
                    // 根据算法名称实例化一个非对称算法提供程序
                    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;
                }
            }
        }
    }


    3、通过 CryptographicBuffer 来实现 string hex base64 binary 间的相互转换
    Crypto/CryptographicBufferDemo.xaml.cs

    /*
     * 通过 CryptographicBuffer 来实现 string hex base64 binary 间的相互转换
     * 
     * 注:CryptographicBuffer 相当于加解密过程中的一个辅助类
     */
    
    using Windows.Security.Cryptography;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Crypto
    {
        public sealed partial class CryptographicBufferDemo : Page
        {
            public CryptographicBufferDemo()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 将 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);
    
                // 将 十六 进制编码字符串转换为 IBuffer 对象
                // IBuffer CryptographicBuffer.DecodeFromHexString(string value);
    
                // 将 IBuffer 对象中的数据转换为 base64 编码字符串
                // string CryptographicBuffer.EncodeToBase64String(IBuffer buffer);
    
                // 将 IBuffer 对象中的数据转换为 十六 进制编码字符串
                // string CryptographicBuffer.EncodeToHexString(IBuffer buffer);
    
                // 生成一个 uint 类型的随机数
                // uint CryptographicBuffer.GenerateRandomNumber();
    
                // 根据指定长度生成一个包含随机数据的 IBuffer 对象
                // IBuffer CryptographicBuffer.GenerateRandom(uint length);
    
                // 比较两个 IBuffer 对象是否相等
                // bool CryptographicBuffer.Compare(IBuffer object1, IBuffer object2);
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    物联网操作系统HelloX开发者入门指南
    【 D3.js 高级系列 】 总结
    【 D3.js 高级系列 — 10.0 】 思维导图
    android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
    OpenGL 顶点缓存对象
    OpenGL顶点数组
    【 D3.js 高级系列 — 9.0 】 交互式提示框
    如何在 Linux 上录制你的终端操作
    程序员诗词大赛开始了_你看过吗?
    程序员与代码的搞笑日常
  • 原文地址:https://www.cnblogs.com/webabcd/p/3120427.html
Copyright © 2011-2022 走看看