• 利用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();
            }
        }
    主程序代码

    运行效果:

    (完)

  • 相关阅读:
    共享内存
    文件IO函数和标准IO库的区别
    链表程序
    flash_header.S ( freescale imx6 board)
    深入理解二维数组
    putchar和puts
    指针目标
    C语言:break和continue
    C语言:输入输出
    python lambda
  • 原文地址:https://www.cnblogs.com/tang-tang/p/6370557.html
Copyright © 2020-2023  润新知