zoukankan      html  css  js  c++  java
  • 【.NET】对文件的对称加密

    using System;
    using System.IO;
    using System.Security.Cryptography;

    namespace ConsoleApp_SymmetricalEncryption
    {
    class Program
    {
    static void Main(string[] args)
    {
    SymmetricalEncryption ss = new SymmetricalEncryption();

    ss.EncryptFile(@"C:error.txt", @"C:error_EncryptFile.txt", ss.Key);
    Console.WriteLine("加密成功!");
    Console.ReadKey();
    ss.DecryptFile(@"C:error_EncryptFile.txt", @"C:error_DecryptFile.txt", ss.Key);
    Console.WriteLine("解密成功!");
    Console.ReadKey();
    }
    }

    /// <summary>
    /// 对文件使用对称加密算法
    /// </summary>
    public class SymmetricalEncryption
    {
    /* 对称加密:
    * 需要发送者和接收者协定一个密钥K,K可以是一个密钥对,但必须是加密密钥和解密密钥之间能够互相推算出来的。
    * 常用的对称加密算法中,加密解密共享一个密钥。
    * 本例中使用的是同一个密钥;
    *
    * 非对称加密:
    * 有一个密钥对,分别为 公钥、私钥(公钥用来加密,私钥用来解密)
    * 私钥永远不需要传递给对方;
    *
    * 优缺点比较:
    * 非对称加密算法复杂,导致加解密速度慢,只适合与数据量小的场合。
    * 对称加密解密效率高,系统开销小,适合金星大数据量的加解密。(大文件一般适合使用对称加密)
    */

    /// <summary>
    /// 随机产生的密钥(也可以自己指定)
    /// 【注意:对称加密算法 加密解密用的Key值是相同的(非对称加密才分:公钥和私钥)】
    /// </summary>
    public string Key = Guid.NewGuid().ToString().Replace("-", "").ToUpper() + Guid.NewGuid().ToString().Replace("-", "").ToUpper();

    /// <summary>
    /// 缓冲区大小
    /// </summary>
    private int bufferSize = 128 * 1024;

    /// <summary>
    /// 密钥salt
    /// </summary>
    private byte[] salt = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
    //salt用来防止穷举暴力破解(salt是在密钥导出之前在密码末尾引入的随机字节,它使得这类攻击变得非常困难)

    /// <summary>
    /// 初始化向量
    /// </summary>
    private byte[] iv = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
    //初始化向量iv起到的也是增强破解难度的作用

    /// <summary>
    /// 初始化 并返回对称加密算法
    /// </summary>
    /// <param name="argKey"></param>
    /// <param name="argSalt"></param>
    /// <returns></returns>
    private SymmetricAlgorithm CreateRijindael(string argKey, byte[] argSalt)
    {
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(argKey, argSalt, "SHA256", 1000);
    SymmetricAlgorithm sma = Rijndael.Create();
    sma.KeySize = 256;
    sma.Key = pdb.GetBytes(32);
    sma.Padding = PaddingMode.PKCS7;
    return sma;
    }

    /// <summary>
    /// 加密文件
    /// </summary>
    /// <param name="argInFile">输入文件</param>
    /// <param name="argOutFile">输出加密后的文件</param>
    /// <param name="argKey">加密用的Key</param>
    public void EncryptFile(string argInFile, string argOutFile, string argKey)
    {
    using (FileStream inFileStream = File.OpenRead(argInFile),
    outFileStream = File.Open(argOutFile, FileMode.OpenOrCreate))
    using (SymmetricAlgorithm algorithm = CreateRijindael(argKey, salt))
    {
    algorithm.IV = iv;
    using (CryptoStream cryptoStream = new CryptoStream(outFileStream, algorithm.CreateEncryptor(),
    CryptoStreamMode.Write))
    {
    byte[] bytes = new byte[bufferSize];
    int readSize = -1;
    while ((readSize = inFileStream.Read(bytes, 0, bytes.Length)) != 0)
    {
    cryptoStream.Write(bytes, 0, readSize);
    }
    cryptoStream.Flush();
    }
    }
    }

    /// <summary>
    /// 解密文件
    /// </summary>
    /// <param name="argInFile">输入待解密的文件</param>
    /// <param name="argOutFile">输出解密后的文件</param>
    /// <param name="argKey">加密用的Key</param>
    public void DecryptFile(string argInFile, string argOutFile, string argKey)
    {
    try
    {
    using (FileStream inFileStream = File.OpenRead(argInFile), outFileStream = File.OpenWrite(argOutFile))
    using (SymmetricAlgorithm algorithm = CreateRijindael(argKey, salt))
    {
    algorithm.IV = iv;
    using (CryptoStream cryptoStream = new CryptoStream(inFileStream, algorithm.CreateDecryptor(),
    CryptoStreamMode.Read))
    {
    byte[] bytes = new byte[bufferSize];
    int readSize = -1;
    int numReads = (int)(inFileStream.Length / bufferSize);
    int slack = (int)(inFileStream.Length % bufferSize);
    for (int i = 0; i < numReads; ++i)
    {
    readSize = cryptoStream.Read(bytes, 0, bytes.Length);
    outFileStream.Write(bytes, 0, readSize);
    }
    if (slack > 0)
    {
    readSize = cryptoStream.Read(bytes, 0, (int)slack);
    outFileStream.Write(bytes, 0, readSize);
    }
    outFileStream.Flush();
    }
    }
    }
    catch (Exception ex)
    {
    throw new Exception("解密失败:" + ex.Message);//可能是密钥输入的不正确,或者文件被修改过
    }
    }

    }
    }

  • 相关阅读:
    央企国管公积金提取。本人实际经历 2013年6月5日
    一台机器开启多个tomcat7 绿色版
    给Repeater、Datalist和Datagrid增加自动编号列
    有关比较分析的MDX
    01[转Cognos8第三讲]Cognos8的安装与配置
    BI前端工具对比
    转摘cognos学习笔记
    04[转Cognos8第四讲]权限配置(2)
    如何更改oracle字符集
    IBM Cognos BI 最佳实践: 定制 IBM Cognos 8 UI
  • 原文地址:https://www.cnblogs.com/jx270/p/3618027.html
Copyright © 2011-2022 走看看