C#加解密

简介: C#加解密

加密解密在开发中经常用到,比如登录密码加密解密、消息传输加密解密等。但是很多人只会使用不理解其中的原理,这篇文章就带领大家快速学习加密解密的原理和使用。


零、什么是加密解密

通俗的说加密解密就是将不想让别人很容易看到的东西根据一定的规则进行处理,形成无规则的内容。拿到加密后内容的人通过一定规则将加密后的内容还原成原文。这里所说的原文在计算机中被称为明文,加密后的内容被称为密文。加密后的内容并不是完全不可破解的,只是提高了破解的难度,让大多数人退缩。那么怎么判断一个加解密安全呢?一般来说加密消息在发送方和接收方进行传递时必须满足三个条件:


  1. 发送方可以确定所发送的消息只有预期接收方可以解密,但不保证其他非接收方获得密文,只要保证非接收方获得密文后无法解密即可;
  2. 接收方可以确定消息是谁发送的;
  3. 接收方可以确定消息在传输过程中没有被篡改,也就是说可以验证消息的完整性。

一般来说常用的加密方式有三种:

  1. 不可逆加密;
  2. 对称可逆加密;
  3. 非堆成可逆加密。

下面我来讲一讲这三种常用的加密方式。

一、不可逆加密

常用的不可逆加密是 MD5 加密,MD5是Message-Digest Algorithm 5英文简称,MD5 的特点如下:


  1. 任意长度的输入,经过 MD5 处理后都会输出128位的信息,这个信息称作数字指纹;
  2. 输入不同的信息产生的数字指纹不一样,数字指纹是全球唯一的;
  3. 无法根据数字指纹推导出加密前的信息。

MD5 我们经常用在文档防篡改、密码加密、数字签名、网盘秒传。针对这四个方面我下面简单讲解一下:

  1. 文档防篡改

在文档发送前记录文档的 MD5 值,接收方收到文档后计算文档的 MD5 值,如果两个 MD5 值不一样就说明文档在发送过程中被篡改过。

  1. 密码加密

如果将密码明文存储在数据库中,泄露后可以别人可以直接登录,在用 MD5 将密码加密后即使泄露了也无法通过密文直接登录。但是这里需要注意,目前网上有很多破解 MD5 密文的网站,这些网站说白了就是利用撞库实现的,这些网站收集了常用的密码组合方式,比如生日、连续相同的数字或密码等,因此我们在验证密码强度时应当将常见的简单密码列,针对所有密码最好将密码中加入随机的信息内容然后再进行 MD5 加密,这就是所谓的加盐。

  1. 数字签名

某人写了一个重要文件,这个文件经过认证机构利用 MD5 生成摘要信息进行认证,如果以后这个人不承认这个文件是他写的,只需认证机构再次对文件生成摘要信息和以前的照耀信息进行对比即可知道该文件是所写的。

  1. 网盘秒传

网盘记录文件第一次上传的 MD5 值,以后当有人上传具有相同 MD5 值的文件时只需要将存在于网盘中的这个文件的链接发送出去即可。

MD5 的实现很简单代码如下:

public class MD5
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="source">待加密字串</param>
    /// <param name="length">加密结果长度</param>
    /// <returns>加密后的字串</returns>
    public string Encrypt(string source, int length = 32)
    {
        if (string.IsNullOrEmpty(source))
        {
            return string.Empty;
        }
        HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
        byte[] bytes = Encoding.UTF8.GetBytes(source);
        byte[] hashValue = provider.ComputeHash(bytes);
        StringBuilder sb = new StringBuilder();
        switch (length)
        {
            case 16:
                for (int i = 4; i < 12; i++)
                {
                    sb.Append(hashValue[i].ToString("x2"));
                }
                break;
            case 32:
                for (int i = 0; i < 16; i++)
                {
                    sb.Append(hashValue[i].ToString("x2"));
                }
                break;
            default:
                for (int i = 0; i < hashValue.Length; i++)
                {
                    sb.Append(hashValue[i].ToString("x2"));
                }
                break;
        }
        return sb.ToString();
    }
    /// <summary>
    /// 获取文件的MD5
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public string AbstractFile(string fileName)
    {
        FileStream file = new FileStream(fileName, FileMode.Open);
        System.Security.Cryptography.MD5 md5 = new MD5CryptoServiceProvider();
        byte[] retVal = md5.ComputeHash(file);
        file.Close();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < retVal.Length; i++)
        {
            sb.Append(retVal[i].ToString("x2"));
        }
        return sb.ToString();
    }
}

二、对称可逆加密

对称可逆加密就是用密钥将需要加密的内容进行加密,然后将加密后的内容发送给接收方,接收方街道内容后利用相同的密钥进行解密后就拿到了明文。对称可逆加密方式有一个严重的问题就是要保证密钥的安全,一旦密钥泄密第三方就可以利用这个密钥对解密收到的密文,甚至可以利用密钥伪造信息发送给接收方,接收方也就无法分辨出到底是谁发送的密文。

最常用的对称可逆加密算法是 DES ,下面我们通过代码看一下 DES 的实现:

public class DES
{
    /// <summary>
    /// 密钥
    /// </summary>
    private byte[] key = ASCIIEncoding.ASCII.GetBytes("123456");
    /// <summary>
    /// 偏移量
    /// </summary>
    private byte[] iv = ASCIIEncoding.ASCII.GetBytes("123456".Insert(0, "w").Substring(0, 8));
    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="text">需要加密的值</param>
    /// <returns>加密后的结果</returns>
    public string Encrypt(string text)
    {
        DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
        using (MemoryStream memStream = new MemoryStream())
        {
            CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            StreamWriter sWriter = new StreamWriter(crypStream);
            sWriter.Write(text);
            sWriter.Flush();
            crypStream.FlushFinalBlock();
            memStream.Flush();
            return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
        }
    }
    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="encryptText"></param>
    /// <returns>解密后的结果</returns>
    public string Decrypt(string encryptText)
    {
        DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
        byte[] buffer = Convert.FromBase64String(encryptText);
        using (MemoryStream memStream = new MemoryStream())
        {
            CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(key, iv), CryptoStreamMode.Write);
            crypStream.Write(buffer, 0, buffer.Length);
            crypStream.FlushFinalBlock();
            return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
        }
    }
}

三、非对称可逆加密

非对称加密比较麻烦,发送方和接收方都保存有两个密钥,其中一个密钥是公钥,公钥是对外公开的,任何人都可以拿到,另一个是私钥,每个人的私钥不一样。规则是由A公钥加密的信息只能用A的私钥解密,由A的私钥加密的消息只能由A的公钥解密。

非对称可逆加密的模式由两种:


  1. 加密模式

使用接收方的公钥加密,然后使用接收方的私钥解密,这样可以保证只有特定的接收方能收到信息,但是无法确认发送方是谁。

  1. 认证模式

使用发送方的私钥加密,然后使用发送方的公钥解密,这样可以保证特定发送方发送消息,但是无法确定消息是发给了谁。

从上述两种模式的描述中我们可以看到他们存在问题,因此就出现了数字签名,在上述认证模式中加入了散列算法(例如MD5),对明文进行处理后再把信息进行加密后发送出去,接收方收到信息解密后比较信息的散列值和原始消息的散列值就可以确定信息是否被篡改。

常用的非对称可逆加密算法常用的是RSA,代码实现如下:

public class Rsa
{
    /// <summary>
    /// 获取加密/解密对
    /// </summary>
    /// <returns>Encrypt   Decrypt</returns>
    public static KeyValuePair<string, string> GetKeyPair()
    {
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        string publicKey = RSA.ToXmlString(false);
        string privateKey = RSA.ToXmlString(true);
        return new KeyValuePair<string, string>(publicKey, privateKey);
    }
    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="content"></param>
    /// <param name="encryptKey">加密key</param>
    /// <returns></returns>
    public static string Encrypt(string content, string encryptKey)
    {
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(encryptKey);
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        byte[] DataToEncrypt = ByteConverter.GetBytes(content);
        byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
        return Convert.ToBase64String(resultBytes);
    }
    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="content"></param>
    /// <param name="decryptKey">解密key</param>
    /// <returns></returns>
    public static string Decrypt(string content, string decryptKey)
    {
        byte[] dataToDecrypt = Convert.FromBase64String(content);
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSA.FromXmlString(decryptKey);
        byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        return ByteConverter.GetString(resultBytes);
    }
    /// <summary>
    /// 产生一组新的密钥
    /// </summary>
    /// <param name="content"></param>
    /// <param name="encryptKey">加密key</param>
    /// <param name="decryptKey">解密key</param>
    /// <returns>加密后结果</returns>
    private static string Encrypt(string content, out string publicKey, out string privateKey)
    {
        RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
        publicKey = rsaProvider.ToXmlString(false);
        privateKey = rsaProvider.ToXmlString(true);
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        byte[] DataToEncrypt = ByteConverter.GetBytes(content);
        byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
        return Convert.ToBase64String(resultBytes);
    }
}

总结

上述三种加密方式在开发中会经常用到,根据我在开发中的经验我建议使用非对称加密,这样更安全。

目录
相关文章
|
3月前
|
算法 C# 数据安全/隐私保护
C# | AES加解密 - 快速上手
这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 。 AES作为计算机领域最常见的通用加密算法之一,称之为对称加密算法中的一哥也丝毫不为过,其重要程度不言而喻。 本文将极尽详细的讲解C#实现AES加密和解密的全过程。
234 0
C# | AES加解密 - 快速上手
|
安全 算法 C#
C# 中使用 RSA加解密算法
一、什么是RSA   RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。      在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
2286 0
|
C# 数据安全/隐私保护
C#加解密
MD5: //Winform: public static string StringToMD5Hash(string inputString) { MD5CryptoSer...
1021 0
|
3月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
150 3
|
3月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
162 3
|
16天前
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
39 7