zoukankan      html  css  js  c++  java
  • 重新想象 Windows 8 Store Apps (31) 加密解密: 哈希算法, 对称算法

    [源码下载]


    重新想象 Windows 8 Store Apps (31) - 加密解密: 哈希算法, 对称算法



    作者:webabcd


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

    • hash 算法(MD5, SHA1, SHA256, SHA384, SHA512)
    • hmac 算法(MD5, SHA1, SHA256, SHA384, SHA512)
    • 本地数据的加密解密
    • 对称算法(AES, DES, 3DES, RC2, RC4)



    示例
    1、演示如何使用 hash 算法(MD5, SHA1, SHA256, SHA384, SHA512)
    Crypto/Hash.xaml.cs

    /*
     * 演示如何使用 hash 算法(MD5, SHA1, SHA256, SHA384, SHA512)
     */
    
    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);
                    // hashAlgorithm.HashLength - 哈希后的值的长度,单位:字节
    
                    // 原文的二进制数据
                    IBuffer vector = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
    
                    // 哈希二进制数据
                    IBuffer digest = hashAlgorithm.HashData(vector);
    
                    lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(digest);
                    lblMsg.Text += Environment.NewLine;
    
    
    
                    // 创建一个可重用的 CryptographicHash 对象
                    CryptographicHash reusableHash = hashAlgorithm.CreateHash();
                    reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("i ", BinaryStringEncoding.Utf8)); // 向 CryptographicHash 中追加需要哈希的二进制数据
                    reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("am ", BinaryStringEncoding.Utf8)); // 向 CryptographicHash 中追加需要哈希的二进制数据
                    reusableHash.Append(CryptographicBuffer.ConvertStringToBinary("webabcd", BinaryStringEncoding.Utf8)); // 向 CryptographicHash 中追加需要哈希的二进制数据
    
                    // 获取哈希后的数据,然后清空 CryptographicHash 中的数据
                    digest = reusableHash.GetValueAndReset();
    
                    lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(digest);
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += Environment.NewLine;
                }
            }
        }
    }


    2、演示如何使用 hmac 算法(HMAC_MD5, HMAC_SHA1, HMAC_SHA256, HMAC_SHA384, HMAC_SHA512)
    Crypto/Hmac.xaml.cs

    /*
     * 演示如何使用 hmac 算法(HMAC_MD5, HMAC_SHA1, HMAC_SHA256, HMAC_SHA384, HMAC_SHA512)
     * 
     * 注:hmac 相当于带密钥的 hash,可以理解为将信息用密钥加密后再哈希
     */
    
    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)
                {
                    // 根据算法名称实例化一个 hmac 算法提供程序
                    MacAlgorithmProvider hmacAlgorithm = MacAlgorithmProvider.OpenAlgorithm(algorithmName);
                    // hmacAlgorithm.MacLength - hmac 后的值的长度,单位:字节
    
                    // 创建一个用于 hmac 算法的随机的 key
                    IBuffer key = CryptographicBuffer.GenerateRandom(hmacAlgorithm.MacLength);
    
                    // 根据 key 生成 CryptographicKey 对象
                    CryptographicKey hmacKey = hmacAlgorithm.CreateKey(key);
    
                    // 根据 hmacKey 签名指定的内容
                    IBuffer signature = CryptographicEngine.Sign(
                        hmacKey, // 签名时所用的 key
                        CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8) // 需要签名的内容
                    );
    
                    lblMsg.Text += algorithmName + ": " + CryptographicBuffer.EncodeToHexString(signature) + " (key: " + CryptographicBuffer.EncodeToHexString(key) + ")";
                    lblMsg.Text += Environment.NewLine;
    
    
    
                    // 验证签名
                    bool isAuthenticated = CryptographicEngine.VerifySignature(
                        hmacKey, // 签名时所用的 key
                        CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8), // 需要签名的内容
                        signature // 签名后的值
                    );
    
                    lblMsg.Text += "isAuthenticated: " + isAuthenticated;
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += Environment.NewLine;
                }
            }
        }
    }


    3、演示如何对本地数据进行加密和解密
    Crypto/LocalCrypto.xaml.cs

    /*
     * 演示如何对本地数据进行加密和解密
     */
    
    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 - Local=user 用户级别的本地加解密;LOCAL=machine - 机器级别的本地加解密
                DataProtectionProvider provider = new DataProtectionProvider("Local=user"); // "LOCAL=machine"
    
                // 原文的二进制数据
                IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
    
                // 加密数据
                IBuffer encrypted = await provider.ProtectAsync(buffer);
                // provider.ProtectStreamAsync(); 加密 stream 类型的数据
    
                // 加密后的结果
                lblMsg.Text += "encrypted: " + CryptographicBuffer.EncodeToHexString(encrypted);
                lblMsg.Text += Environment.NewLine;
    
    
                
                // 实例化用于解密的 DataProtectionProvider
                DataProtectionProvider provider2 = new DataProtectionProvider();
    
                // 解密数据
                IBuffer decrypted = await provider2.UnprotectAsync(encrypted);
                // provider2.UnprotectStreamAsync(); // 解密 stream 类型的数据
    
                // 解密后的结果
                lblMsg.Text += "decrypted: " + CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decrypted);
                lblMsg.Text += Environment.NewLine;
            }
    
        }
    }


    4、演示如何使用对称算法(AES, DES, 3DES, RC2, RC4)
    Crypto/Symmetric.xaml.cs

    /*
     * 演示如何使用对称算法(AES, DES, 3DES, RC2, RC4)
     */
    
    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)
            {
                // 本示例的原文为 16 个字节,是为了正常演示无填充时的加密
                // 什么是填充:比如 aes 要求数据长度必须是 16 的倍数,如果不是则需要通过指定的填充模式来补全数据
                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")) // AES 算法密钥长度 128 位
                        keySize = 128;
                    else if (algorithmName.StartsWith("DES")) // DES 算法密钥长度 64 位(56 位的密钥加上 8 位奇偶校验位)
                        keySize = 64;
                    else if (algorithmName.StartsWith("3DES")) // 3DES 算法密钥长度 192 位(3 重 DES)
                        keySize = 192;
                    else if (algorithmName.StartsWith("RC2")) // RC2 算法密钥长度可变
                        keySize = 128;
                    else if (algorithmName.StartsWith("RC4")) // RC4 算法密钥长度可变
                        keySize = 128;
    
                    IBuffer buffer; // 原文
                    IBuffer encrypted; // 加密后
                    IBuffer decrypted; // 解密后
                    IBuffer iv = null; // 向量(CBC 模式)
    
                    // 根据算法名称实例化一个对称算法提供程序
                    SymmetricKeyAlgorithmProvider symmetricAlgorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
    
                    // 创建一个随机密钥 key
                    IBuffer key = CryptographicBuffer.GenerateRandom(keySize / 8);
    
                    // 根据 key 生成 CryptographicKey 对象
                    CryptographicKey cryptoKey = symmetricAlgorithm.CreateSymmetricKey(key);
    
                    // 如果是 CBC 模式则随机生成一个向量
                    if (algorithmName.Contains("CBC"))
                        iv = CryptographicBuffer.GenerateRandom(symmetricAlgorithm.BlockLength);
    
                    // 将需要加密的数据转换为 IBuffer 类型
                    buffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
    
                    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 = Windows.Security.Cryptography.Core.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;
                }
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    LeetCode (160) Intersection of Two Linked Lists
    cmake命令 安装、用法简介
    算法——回文解密,判断一个数组是否为回文
    发现一个好用的播放插件---ckplayer
    阿里云ESC上的Ubuntu图形界面的安装
    tomcat 启动本地项目,但是报错的是另一个项目错误导致的tomcat启动失败
    发现一个有趣的时间控件
    Comparator 排序优先级
    项目Exception,项目前面有红色的小叉×
    日常问题,JasperException
  • 原文地址:https://www.cnblogs.com/webabcd/p/3114657.html
Copyright © 2011-2022 走看看