天天看點

WinRT下的RSA加解密方法

        RSA公鑰加密算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。

        本文旨在針對WinRT下RSA加密方法的使用進行示範,希望僅為尋找WinRT下RSA加密可用類的小夥伴不用再尋尋覓覓。

        介紹分兩步,一是建立RSA工具類,友善調用,二是舉個簡單的例子。

        一、建立RSA工具類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

namespace UIDemo
{
    public class RSA
    {

        /// <summary>
        /// 産生一對RSA密鑰對,公鑰加密,私鑰解密。
        /// 應該靜态的儲存要使用的密鑰對
        /// </summary>
        /// <returns></returns>
        public static RSAKeyPair CreateRSAKeyPair()
        {
            AsymmetricKeyAlgorithmProvider asym = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
            CryptographicKey key = asym.CreateKeyPair(1024);

            IBuffer privateKeyBuffer = key.Export(CryptographicPrivateKeyBlobType.Capi1PrivateKey);
            IBuffer publicKeyBuffer = key.ExportPublicKey(CryptographicPublicKeyBlobType.Capi1PublicKey);

            byte[] privateKeyBytes;
            byte[] publicKeyBytes;

            CryptographicBuffer.CopyToByteArray(privateKeyBuffer, out privateKeyBytes);
            CryptographicBuffer.CopyToByteArray(publicKeyBuffer, out publicKeyBytes);

            string privateKey = Convert.ToBase64String(privateKeyBytes);
            string publicKey = Convert.ToBase64String(publicKeyBytes);

            return new RSAKeyPair(privateKey, publicKey);
        }

        /// <summary>
        /// 使用公鑰加密
        /// </summary>
        /// <param name="publicKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Encrypt(string publicKey, string data)
        {
            IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(publicKey);

            AsymmetricKeyAlgorithmProvider asym = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
            CryptographicKey key = asym.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.Capi1PublicKey);

            IBuffer plainBuffer = CryptographicBuffer.ConvertStringToBinary(data, BinaryStringEncoding.Utf8);
            IBuffer encryptedBuffer = CryptographicEngine.Encrypt(key, plainBuffer, null);

            byte[] encryptedBytes;
            CryptographicBuffer.CopyToByteArray(encryptedBuffer, out encryptedBytes);

            return encryptedBytes;
        }

        /// <summary>
        /// 使用私鑰解密
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string Decrypt(string privateKey, byte[] data)
        {
            IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(privateKey);

            AsymmetricKeyAlgorithmProvider asym = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
            CryptographicKey key = asym.ImportKeyPair(keyBuffer, CryptographicPrivateKeyBlobType.Capi1PrivateKey);

            IBuffer plainBuffer = CryptographicEngine.Decrypt(key, WindowsRuntimeBufferExtensions.AsBuffer(data), null);

            byte[] plainBytes;
            CryptographicBuffer.CopyToByteArray(plainBuffer, out plainBytes);

            return Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
        }


    }

    /// <summary>
    /// RSA 的公鑰與私鑰
    /// </summary>
    public class RSAKeyPair
    {
        public string PrivateKey { get; set; }
        public string PublicKey { get; set; }

        public RSAKeyPair(string privateKey, string publicKey)
        {
            PrivateKey = privateKey;
            PublicKey = publicKey;
        }
    }
}
           

        二、使用示例如下

RSAKeyPair kp = new RSAKeyPair(null, null);
            // 通過以下語句生成一對密鑰,再儲存起來。其中公鑰公開給加密方使用,私鑰解密用。已儲存則加載。
            // RSAKeyPair kp = RSA.CreateRSAKeyPair();

            // 加載靜态密鑰對
            kp.PrivateKey = "BwIAAACkAABSU0EyAAQAAAEAAQBTiebuzvfndZCcc82O3ax0nRz0U20cDwWDuCKUIpdBPfNQD4gSp61RhMaX0x70IoY2oqnUGlQK1sYZ1vG9F7F7zIIAZVnb+3JwhcHU/4NVbMuS7+NDs5ncOUgiMO2Aj2KNB81gCcYmciv4FiuB8klGiHTwCV0GzrzXTBe/QavjujGOMjswtDFoBa2dgAmhnQXdpJoGRe3cZsyAXNQQvfdvOK/9i732O7DBle71ec0cY7T+993Z39QenI6X3s7N/NPDWhc7klLY04C950BKofjFV4HNVO4QhkTujpPnyfFnI0KVJGwit+tkS65pTBVdZ++EwgMQZug5CRHB2eG347DhsbJZXToWtTbzrDbVU6Oh2fvTYjWRopH4RiJnljr3rHNkBY05qat+jMaiBC8LRn6xUUyp6F3zhCRjcpgdefb/Jt+ujRTHEFOVLGR3S+PVD5/G0plhTW9QbOk30Zp/Tci2gWUs6tEXUElSYrlZJg0PZYVTSACinPzfE4t0tySfessaetdwVlarLjAejnWlx4CT+5BgV55I9FOmdjJSzYK6q4vwnlBOpyvwfL6kJlTW49vat1Syb/TmsjEz4sceDX890Wd0er5S/+eLvhiPfhhplQa2h2PyIOj0pStbF6W5BMV7b1P4JHdDRaQHaTBKMQFXDaFSpWgNbBAELfXHtsGBxcQ5smM1WNOsfYqrKg0OJaxu30QtrAIp0ucZWH1RtuOcneEndeTMtLXkG1vc5m7O9IFzv6GINlcRCZ6MGmbWzxY=";
            kp.PublicKey = "BgIAAACkAABSU0ExAAQAAAEAAQBTiebuzvfndZCcc82O3ax0nRz0U20cDwWDuCKUIpdBPfNQD4gSp61RhMaX0x70IoY2oqnUGlQK1sYZ1vG9F7F7zIIAZVnb+3JwhcHU/4NVbMuS7+NDs5ncOUgiMO2Aj2KNB81gCcYmciv4FiuB8klGiHTwCV0GzrzXTBe/Qavjug==";

            // 加密後形成的加密位元組數組
            byte[] miBytes = RSA.Encrypt(kp.PublicKey, "hello world!");
            // Base64編碼文本
            string miBase64 = CryptographicBuffer.EncodeToBase64String(WindowsRuntimeBufferExtensions.AsBuffer(miBytes));
 
            // 解密
            CryptographicBuffer.CopyToByteArray(CryptographicBuffer.DecodeFromBase64String(miBase64), out miBytes);
            string ori = RSA.Decrypt(kp.PrivateKey, miBytes);
            txtInfo.Text = ori;