C#(99):加密与解密 Sytem.Security.CryptoGraphy

摘要:
1.使用抽象类HashAlgorithm//明文密码从字符串转换为字节数组byte[]clearBytes=编码。违约获取字节(“123”);

一、Hash加密,使用HashAlgorithm哈希算法类的派生类(MD5、SHA1等)

特点:只能加密,不可逆。可对目标信息生成一段特定长度唯一的Hash值。

HashAlgorithm派生类包括:

  1. KeyedHashAlgorithm: 显示所有加密哈希算法实现均必须从中派生的抽象类。
  2.  MD5: 表示 MD5 哈希算法的所有实现均从中继承的抽象类。
    ————MD5Crypto​Service​Provider:使用加密服务提供程序 (CSP) 提供的实现,计算输入数据的 MD5 哈希值。
  3. RIPEMD160: 表示 MD160 哈希算法的所有实现均从中继承的抽象类。
  4.  SHA1: 计算输入数据的 SHA1 哈希值。
    ————SHA1Crypto​Service​Provider:使用加密服务提供程序 (CSP) 提供的实现,计算输入数据的 SHA1 哈希值。
  5. SHA256: 计算输入数据的 SHA256 哈希值。
  6. SHA384: 计算输入数据的 SHA384 哈希值。
  7. SHA512: 计算输入数据的 SHA512 哈希值。

1、使用抽象类HashAlgorithm

//明文密码由字符串转换为byte数组
byte[] clearBytes =Encoding.Default.GetBytes("123");

//由明文的byte数组计算出MD5密文byte数组
byte[] hashedBytes = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes);
//把byte数组转换为字符串后返回,BitConverter用于将基础数据类型与字节数组相互转换
string result = BitConverter.ToString(hashedBytes).Replace("-", "");

Console.Write(result);

2、使用抽象类MD5

byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes =  MD5.Create().ComputeHash(clearBytes);

StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hashedBytes.Length; i++)
{
    sBuilder.Append(hashedBytes[i].ToString("x2"));
}
string result = sBuilder.ToString();
Console.Write(result);

3、使用MD5CryptoServiceProvider类

byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes = new MD5CryptoServiceProvider().ComputeHash(clearBytes);
string result = "";
for (int i = 0; i < hashedBytes.Length; i++)
    result += hashedBytes[i].ToString("X").PadLeft(2, '0');

Console.Write(result);

4、Web使用的Hash加密:FormsAuthentication类

FormAuthentication.HashPasswordForStoringInConfigFile(str,"MD5")//或者“SHA1”

5、文件哈希计算

  • MD5是一个将任意长度的数据字符串转化成短的固定长度的值的单向操作。任意两个字符串不应有相同的散列值(即,有“很大可能”是不一样的,并且要人为地创造出来两个散列值相同的字符串应该是困难的)。
  • 因此MD5经常用于校验字符串或者文件,因为如果文件的MD5不一样,说明文件内容也是不一样的,即经过修改的,如果发现下载的文件和给的md5值不一样,就需要慎重使用。
  • MD5文件校验用途非常多,例如:游戏patch包的校验,病毒文件确认,app提审校验等等,只要需要确认某一个文件的唯一性和正确性,都会使用md5作为校验。

输入文件路径,就可以得到对应的哈希值,这个哈希值是对文件本身内容包括文件名字有关,跟文件存放的路径和运行平台,设备无关。

string GetFileHash(string path)
{
    var hash = MD5.Create();//SHA1.Create();
    var stream = new FileStream(path, FileMode.Open);
    byte[] hashByte = hash.ComputeHash(stream);
    stream.Close();
    return BitConverter.ToString(hashByte).Replace("-", "");
}

二、对称加密:使用SymmetricAlgorithm对称算法类的派生类(Aes、DES等)

特点:指加密和解密使用相同密钥的加密算法。

对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。

SymmetricAlgorithm派生类包括:

  1. Aes:表示高级加密标准 (AES) 的所有实现都必须从中继承的抽象基类。
    ————Aes​Crypto​Service​Provider:使用高级加密标准 (AES) 算法的加密应用程序编程接口 (CAPI) 实现来执行对称加密和解密。
  2. DES:表示所有 DES 实现都必须从中派生的数据加密标准 (DES) 算法的基类。
    ————DESCrypto​Service​Provider:定义访问数据加密标准 (DES) 算法的加密服务提供程序 (CSP) 版本的包装对象。
  3. RC2:表示 RC2 算法的所有实现都必须从中派生的基类。
  4. Rijndael:表示 Rijndael 对称加密算法的所有实现必须从其继承的基类。
  5. TripleDES:表示三重数据加密标准算法的基类
public static string strKey = "abcdefgh";//注意:这里的密钥sKey必须能转为8个byte,即输入密钥为8半角个字符或者4个全角字符或者4个汉字的字符串
public static string strIV = "ijklmnop";

// 加密
public static string Encrypt(string _strQ)
{
    byte[] buffer = Encoding.UTF8.GetBytes(_strQ);
    MemoryStream ms = new MemoryStream();
    DESCryptoServiceProvider des = new DESCryptoServiceProvider();
    CryptoStream encStream = new CryptoStream(ms, des.CreateEncryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
    encStream.Write(buffer, 0, buffer.Length);
    encStream.FlushFinalBlock();
    return Convert.ToBase64String(ms.ToArray());
}

// 解密
public static string Decrypt(string _strQ)
{
    byte[] buffer = Convert.FromBase64String(_strQ);
    MemoryStream ms = new MemoryStream();
    DESCryptoServiceProvider des = new DESCryptoServiceProvider();
    CryptoStream encStream = new CryptoStream(ms, des.CreateDecryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
    encStream.Write(buffer, 0, buffer.Length);
    encStream.FlushFinalBlock();
    return Encoding.UTF8.GetString(ms.ToArray());
}

三、非对称加密:使用AsymmetricAlgorithm非对称算法类的派生类(DSA、RSA等)

特点:指加密和解密使用不同密钥的加密算法,也称为公私钥加密。公钥是可以公开用来加密,私匙严格由接受方保密用于加密。

非对称加密的缺点是加解密速度要远远慢于对称加密。

AsymmetricAlgorithm派生类包括:

  1. DSA:表示数字签名算法(DSA)的所有实现都必须从中继承的抽象基类。
    ————DSACryptoServiceProvider:使用加密服务提供程序 (CSP) 提供的 DSA算法的实现执行不对称加密和解密。
  2. ECDiffie​Hellman:
  3. ECDsa:
  4. RSA:表示 RSA 算法的所有实现均从中继承的基类。
    ————RSACrypto​Service​Provider:使用加密服务提供程序 (CSP) 提供的 RSA 算法的实现执行不对称加密和解密。
/// <summary>
/// 获取加密所使用的key,RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
/// </summary>
public static void GetKey()
{
    string PublicKey = string.Empty;
    string PrivateKey = string.Empty;
    RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
    PublicKey = rSACryptoServiceProvider.ToXmlString(false);
    // 获取公匙,用于加密
    PrivateKey = rSACryptoServiceProvider.ToXmlString(true);
    // 获取公匙和私匙,用于解密

    //Console.WriteLine("PublicKey is {0}", PublicKey);        // 输出公匙
    //Console.WriteLine("PrivateKey is {0}", PrivateKey);     // 输出密匙
    //密匙中含有公匙,公匙是根据密匙进行计算得来的。

    using (StreamWriter streamWriter = new StreamWriter("PublicKey.xml"))
    {
        streamWriter.Write(rSACryptoServiceProvider.ToXmlString(false));// 将公匙保存到运行目录下的PublicKey
    }
    using (StreamWriter streamWriter = new StreamWriter("PrivateKey.xml"))
    {
        streamWriter.Write(rSACryptoServiceProvider.ToXmlString(true)); // 将公匙&私匙保存到运行目录下的PrivateKey
    }
}

/// <summary>
/// 加密
/// </summary>
private static string Encryption(string str)
{
    RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
    using (StreamReader streamReader = new StreamReader("PublicKey.xml")) // 读取运行目录下的PublicKey.xml
    {
        rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 将公匙载入进RSA实例中
    }

    byte[] buffer = Encoding.UTF8.GetBytes(str); // 将明文转换为byte[]

    // 加密后的数据就是一个byte[] 数组,可以以 文件的形式保存 或 别的形式(网上很多教程,使用Base64进行编码化保存)
    byte[] EncryptBuffer = rSACryptoServiceProvider.Encrypt(buffer, false); // 进行加密
    return Convert.ToBase64String(EncryptBuffer); // 如果使用base64进行明文化,在解密时 需要再次将base64 转换为byte[]
}

/// <summary>
/// 解密
/// </summary>
private static string Decrypt(string strEncryptBase64)
{
    RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
    using (StreamReader streamReader = new StreamReader("PrivateKey.xml")) // 读取运行目录下的PrivateKey.xml
    {
        rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 将私匙载入进RSA实例中
    }

    byte[] buffer = Convert.FromBase64String(strEncryptBase64);
    // 解密后得到一个byte[] 数组
    byte[] DecryptBuffer = rSACryptoServiceProvider.Decrypt(buffer, false); // 进行解密
    string str = Encoding.UTF8.GetString(DecryptBuffer); // 将byte[]转换为明文

    return str;
}

    免责声明:文章转载自《C#(99):加密与解密 Sytem.Security.CryptoGraphy》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

    上篇go语言中的反射reflectibatis 批量插入下篇

    宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

    相关文章

    log4cplus基本用法

    说起日志系统,不得不提大名鼎鼎的Log4j。特别是使用Java的人们,能够说是无人不知无人不晓无人不用。 Log4j以其简单的使用方式(引入一个jar包。一行代码就可以调用)。灵活(可通过配置文件任意配置),功能强大(多个级别。可配置多个输出目的地,Console,File。系统日志。远端的LogServer等等,可订制日志格式,自己主动产生,删除日志...

    Vue之日历控件vue-full-calendar的使用

    (1).安装依赖 npm install vue-full-calendar  npm install moment 因为这是日历插件用到了时间工具类 === moment  (2).文件中导入依赖 在想要用此插件的文件中导入依赖 import { FullCalendar } from 'vue-full-calendar' import "f...

    Crypto++入门学习笔记(DES、AES、RSA、SHA-256)

    最先附上下载地址 背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以skip): 最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后对一些数据进行一些加密解密的操作。 笔者之前没接触过任何加密解密方面的知识(当然,把每个字符的ASCII值加1之流对明文进行加密的“趣事”还是干过的,当时还很乐在其中。),甚至一开始连Crypto+...

    二分图的最大匹配、完美匹配和匈牙利算法(转载)

    摘自: http://www.renfei.org/blog/bipartite-matching.htm 最大匹配数:最大匹配的匹配边的数目 最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择 最大独立数:选取最多的点,使任意所选两点均不相连 最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径...

    机器视觉之 ICP算法和RANSAC算法

    临时研究了下机器视觉两个基本算法的算法原理 ,可能有理解错误的地方,希望发现了告诉我一下 主要是了解思想,就不写具体的计算公式之类的了 (一) ICP算法(Iterative Closest Point迭代最近点) ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法,如下图1 如下图,假设PR(红色块)和RB(蓝...

    迪杰斯特拉 算法 在游戏中的运用

    迪杰斯特拉 (Dijkstra).是算最短节点的。虽然网上有很多文献资料和代码,不过并不适合我的口味。于是简单的改造了下。 纯手工鼠标画图一张。 static void Main(string[] args) { int n = 7, en = 11; //-1表示不可达 int[,] a = new in...