利用RSACryptoServiceProvider进行RSA加密解密

前言:

本文只介绍How to use,对于加密算法的研究不予讨论。

关于私钥的存储,微软给的建议是使用windows自带的秘钥容器,相见文档

为了直观看到私钥和公钥,本文直接将其存入XML文件中。现实情况则要复杂的多,还牵涉到数字签名、数字证书等。

关于公钥、私钥、数字签名、数字证书的概念,相见阮一峰大神的博客,传送门在这里

 

正文:

由于RSA不适合加密大量数据,所以可以采用DES和RSA混合加密的方法,即先用DES加密数据,再用RSA加密DES的秘钥。

 

RSAHelper 类

public class RSAHelper
    {
        /// <summary>
        /// 读取二进制文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static byte[] GetByte(string path)
        {
            FileInfo fi = new FileInfo(path);
            List<byte> buff = new List<byte>();
            using (FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                BinaryReader br = new BinaryReader(fs);
                try
                {
                    while (true)
                    {
                        byte i = br.ReadByte();
                        buff.Add(i);
                    }
                }
                catch (Exception)
                {
                    br.Close();
                }
            }
            return buff.ToArray();
        }

        /// <summary>
        /// 读取文本文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetText(string path)
        {
            FileInfo fi = new FileInfo(path);
            string content;
            using (FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                StreamReader sr = new StreamReader(fs);
                content = sr.ReadToEnd();
                sr.Close();
            }
            return content;
        }

        /// <summary>
        /// 写入二进制文件
        /// </summary>
        /// <param name="content"></param>
        /// <param name="path"></param>
        public static void WriteByte(byte[] content, string path)
        {
            FileInfo fi = new FileInfo(path);
            using (FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                BinaryWriter br = new BinaryWriter(fs);
                br.Write(content);
                br.Flush();
                br.Close();
            }
        }

        /// <summary>
        /// 写入文本文件
        /// </summary>
        /// <param name="content"></param>
        /// <param name="path"></param>
        public static void WriteText(string content, string path)
        {
            FileInfo fi = new FileInfo(path);
            using (FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                StreamWriter sw = new StreamWriter(fs);
                sw.Write(content);
                sw.Flush();
                sw.Close();
            }
        }

        /// <summary>
        /// RSA加密/解密
        /// </summary>
        /// <param name="data">加密/解密数据</param>
        /// <param name="key">公钥/私钥</param>
        /// <param name="isEncrypt">ture加密,false解密</param>
        /// <returns></returns>
        public static byte[] EncryptOrDecrypt(byte[] data, string key, bool isEncrypt)
        {
            RSACryptoServiceProvider rsaP = new RSACryptoServiceProvider();
            rsaP.FromXmlString(key);
            if (isEncrypt)// 加密
            {
                byte[] buff = rsaP.Encrypt(data, true);
                return buff;
            }
            else // 解密
            {
                byte[] buff = rsaP.Decrypt(data, true);
                return buff;
            }

        } 
    }
RSAHelper类

 

DESHelper 类

public class DESHelper
    {
        /// <summary>
        /// DES加密/解密
        /// </summary>
        /// <param name="data">加密/解密数据</param>
        /// <param name="key">秘钥</param>
        /// <param name="keyIV">向量</param>
        /// <param name="isEncrypt">true加密,false解密</param>
        /// <returns></returns>
        public static byte[] EncryptOrDecrypt(byte[] data, byte[] key, byte[] keyIV, bool isEncrypt)
        {
            DESCryptoServiceProvider desP = new DESCryptoServiceProvider();
            if (isEncrypt)// 加密
            {
                desP.Key = key;
                desP.IV = keyIV;
                ICryptoTransform desencrypt = desP.CreateEncryptor(key, keyIV);
                byte[] result = desencrypt.TransformFinalBlock(data, 0, data.Length);
                return result;
            }
            else // 解密
            {
                desP.Key = key;
                desP.IV = keyIV;
                ICryptoTransform desencrypt = desP.CreateDecryptor(key, keyIV);
                byte[] result = desencrypt.TransformFinalBlock(data, 0, data.Length);
                return result;
            }
        }

        /// <summary>
        /// 创建随机秘钥
        /// </summary>
        /// <returns></returns>
        public static byte[] CreateKey()
        {
            DESCryptoServiceProvider desP = new DESCryptoServiceProvider();
            desP.GenerateKey();
            return desP.Key;
        }

        /// <summary>
        /// 创建随机向量
        /// </summary>
        /// <returns></returns>
        public static byte[] CreateIV()
        {
            DESCryptoServiceProvider desP = new DESCryptoServiceProvider();
            desP.GenerateIV();
            return desP.IV;
        }
    }
DESHelper类

 

主程序代码

class Program
    {
        static void Main(string[] args)
        {
            string rootPath = AppDomain.CurrentDomain.BaseDirectory;
            string RSAPath = Path.Combine(rootPath, "RSA");
            string encryptFilePath = Path.Combine(RSAPath, "加密文件.dll");
            string decryptFilePath = Path.Combine(RSAPath, "解密文件.txt");
            string publicKeyPath = Path.Combine(RSAPath, "RSA公钥.xml");
            string privateKeyPath = Path.Combine(RSAPath, "RSA私钥.xml");
            string DESKeyPath = Path.Combine(RSAPath, "经过RSA加密的DES秘钥.dll");
            string DESIVPath = Path.Combine(RSAPath, "经过RSA加密的DES向量.dll");
            if (Directory.Exists(RSAPath))
            {
                Directory.Delete(RSAPath, true);
            }
            Directory.CreateDirectory(RSAPath);

            Console.WriteLine("请输入要加密的内容:");
            string data = Console.ReadLine();

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            string RSAPublic = rsa.ToXmlString(false);// RSA公钥
            string RSAPrivate = rsa.ToXmlString(true);// RSA私钥
            byte[] DESKey = DESHelper.CreateKey(); // DES秘钥
            byte[] DESIV = DESHelper.CreateIV(); // DES向量
            // DES加密输入内容
            byte[] enData = DESHelper.EncryptOrDecrypt(Encoding.Unicode.GetBytes(data), DESKey, DESIV, true);
            // 写入加密文件
            RSAHelper.WriteByte(enData, encryptFilePath);
            // 写入RSA公钥
            RSAHelper.WriteText(RSAPublic, publicKeyPath);
            // 写入RSA私钥
            RSAHelper.WriteText(RSAPrivate, privateKeyPath);
            // 写入经过RSA加密的DES秘钥
            RSAHelper.WriteByte(RSAHelper.EncryptOrDecrypt(DESKey, RSAPublic, true), DESKeyPath);
            // 写入经过RSA加密的DES向量
            RSAHelper.WriteByte(RSAHelper.EncryptOrDecrypt(DESIV, RSAPublic, true), DESIVPath);

            // 读取RSA私钥
            string privateKey = RSAHelper.GetText(privateKeyPath);
            // 读取DES秘钥并解密
            byte[] realDESKey = RSAHelper.EncryptOrDecrypt(RSAHelper.GetByte(DESKeyPath), privateKey, false);
            // 读取DES向量并解密
            byte[] realDESIV = RSAHelper.EncryptOrDecrypt(RSAHelper.GetByte(DESIVPath), privateKey, false);
            // 读取加密文件
            byte[] enData2 = RSAHelper.GetByte(encryptFilePath);
            // 解密文件
            byte[] deData = DESHelper.EncryptOrDecrypt(enData2, realDESKey, realDESIV, false);
            // 写入解密文件
            RSAHelper.WriteText(Encoding.Unicode.GetString(deData), decryptFilePath);

            Console.WriteLine("加密成功!");
            Console.ReadKey();
        }
    }
主程序代码

 

运行效果:

(完)

 

posted @ 2017-02-06 15:34  唐大兵  阅读(13112)  评论(0编辑  收藏  举报