12-C#

C#.Net-加密解密-学习笔记


一、加密的分类

复制代码
加密
├── 不可逆加密(单向散列)
│   └── MD5
└── 可逆加密
    ├── 对称加密(加密/解密用同一个密钥)
    │   └── DES / AES
    └── 非对称加密(加密/解密用不同密钥)
        └── RSA / ECC

二、MD5 ------ 不可逆加密(哈希散列)

核心特点

特点 说明
不可逆 只能加密,无法从密文还原原文
固定长度 任意长度的内容,结果都是 32 位(16进制字符串)
雪崩效应 原文改动一点点,结果变化非常大
相同输入相同输出 同一原文每次加密结果完全一样
与文件名无关 文件内容不变,改名字不影响 MD5 值

代码示例

csharp 复制代码
// 字符串加密(默认32位)
string hash = MD5Encrypt.Encrypt("123456");

// 16位(取32位结果的第9~24位字符)
string hash16 = MD5Encrypt.Encrypt("123456", 16);

// 文件摘要
string fileHash = MD5Encrypt.AbstractFile(@"C:\test.txt");

核心实现原理

csharp 复制代码
HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
byte[] bytes = Encoding.UTF8.GetBytes(source);
byte[] hashValue = provider.ComputeHash(bytes);
// 把每个字节转成两位16进制字符串拼接
sb.Append(hashValue[i].ToString("x2"));

MD5 的实际用途

1. 防篡改 / 文件校验

  • SVN 等版本管理工具用 MD5 检测文件是否被修改
  • 网盘"极速秒传":扫描本地文件 MD5,与服务器已有文件比对,一致则无需重新上传

2. 密码存储

  • 数据库不能存明文密码,存 MD5 密文

  • 登录时把用户输入的密码 MD5 后与数据库比对

  • 为防止简单密码被暴力破解,通常要加盐

    加盐示例:MD5("123456" + "固定盐值zhaoxi")
    或者:MD5(MD5("123456")) // 二次加密

3. 数字签名 / 防抵赖

  • 对文件内容做 MD5 摘要,由权威第三方保存,证明文件归属

MD5 "被破解"的真相

MD5 本身没有被数学破解,但可以通过**彩虹表(暴力标本库)**反查。

  • 32位 MD5 有 2^128 种可能,不可能全部存储
  • 加盐后,彩虹表基本失效

三、DES ------ 对称可逆加密

核心特点

  • 加密和解密用同一个密钥
  • 速度快,适合大量数据加密
  • 密钥长度固定 8字节
  • 缺点:密钥需要安全传递,一旦泄露全完

代码示例

csharp 复制代码
// 加密
string encrypted = DesEncrypt.Encrypt("Hello World");

// 解密
string original = DesEncrypt.Decrypt(encrypted);

核心实现原理

csharp 复制代码
// 密钥和初始向量都取配置文件中 DesKey 的前8位
private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Substring(0, 8));
private static byte[] _rgbIV  = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Substring(0, 8));

// 加密流程:明文 → CryptoStream(加密器) → MemoryStream → Base64字符串
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
CryptoStream crypStream = new CryptoStream(memStream,
    dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);

密文最终用 Base64 编码输出,方便存储和传输。

同类算法

算法 密钥长度 说明
DES 56位(8字节) 较老,安全性一般
3DES 168位 DES 的增强版
AES 128/192/256位 目前主流,推荐使用

四、RSA ------ 非对称可逆加密

核心概念

RSA 使用一对密钥:公钥(Public Key)和私钥(Private Key)。

密钥 特点 用途
公钥 可以公开给任何人 加密数据 / 验证签名
私钥 只有自己保存 解密数据 / 生成签名

关键原则:两个 key 无法互相推导出对方。

两种使用场景

场景一:保密通信(公钥加密,私钥解密)

复制代码
发送方用接收方的公钥加密 → 只有持有私钥的接收方才能解密
csharp 复制代码
KeyModel keys = RsaEncrypt.GetKeyPair();

// 用公钥加密
string encrypted = RsaEncrypt.Encrypt("Hello", keys.PublicKey);

// 用私钥解密
string original = RsaEncrypt.Decrypt(encrypted, keys.PrivateKey);

场景二:数字签名(私钥签名,公钥验证)

复制代码
发送方用私钥对内容签名 → 任何人用公钥都能验证签名是否合法
csharp 复制代码
// 生成签名(用私钥)
string signature = RsaEncrypt.SignData("消息原文", keys.PrivateKey);

// 验证签名(用公钥)
bool isValid = RsaEncrypt.VerifyData("消息原文", signature, keys.PublicKey);
// 原文被篡改 → false
// 签名被篡改 → false

核心实现原理

csharp 复制代码
// 生成密钥对
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey  = RSA.ToXmlString(false); // false = 只含公钥
string privateKey = RSA.ToXmlString(true);  // true  = 含公钥+私钥

// 加密
rsa.FromXmlString(encryptKey);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);

// 签名(内部用 SHA1 做摘要,再用私钥加密摘要)
byte[] AOutput = oRSA3.SignData(messagebytes, "SHA1");

// 验签
bool bVerify = RSA.VerifyData(messagebytes, "SHA1", messageAutographbytes);

C# 内置 RSA 的限制

C# 内置的 RSACryptoServiceProvider 只支持:

  • 公钥加密 + 私钥解密
  • 私钥签名 + 公钥验签

如果需要"私钥加密 + 公钥解密",需要引入第三方库 BouncyCastle


五、三种加密方式对比总结

对比项 MD5 DES(对称) RSA(非对称)
是否可逆
密钥数量 1个(共享) 2个(公钥+私钥)
速度
安全性 中(需加盐) 中(密钥传递风险)
典型用途 密码存储、文件校验 数据传输加密 安全通信、数字签名

六、实际项目中的常见组合

HTTPS 的工作原理(RSA + AES 组合):

  1. 服务器把公钥发给客户端
  2. 客户端生成一个随机的 AES 密钥,用公钥加密后发给服务器
  3. 服务器用私钥解密,得到 AES 密钥
  4. 后续通信全部用 AES 对称加密(速度快)

这样既解决了对称加密密钥传递不安全的问题,又保证了通信速度。


七、配置文件读取(扩展知识)

项目中通过 appsettings.json 存储 DES 密钥,用 Microsoft.Extensions.Configuration 读取:

json 复制代码
{
  "DesKey": "Richard123456"
}
csharp 复制代码
IConfigurationBuilder builder = new ConfigurationBuilder()
    .AddJsonFile("appSettings.json");
IConfigurationRoot configuration = builder.Build();
string desKey = configuration.GetSection("DesKey").Value;

密钥不要硬编码在代码里,放配置文件或环境变量更安全。

相关推荐
hanbr1 小时前
【C++ STL核心】vector:最常用的动态数组容器(第九天核心)
开发语言·c++
FirstFrost --sy2 小时前
MySQL关于表的操作
数据库·mysql
菜鸟‍2 小时前
【后端项目】苍穹外卖day01-开发环境搭建
java·开发语言·spring boot
青槿吖3 小时前
【保姆级教程】Spring事务控制通关指南:XML+注解双版本,避坑指南全奉上
xml·java·开发语言·数据库·sql·spring·mybatis
Yungoal3 小时前
B/S和C/S架构在服务端接收请求
c语言·开发语言·架构
浪潮IT馆3 小时前
Windows 达梦 8(DM8)数据库完整安装教程 + 命令行导入 .dmp 文件完整指南
数据库·windows
Dylan~~~3 小时前
Redis MCP Server:让 AI 拥有“持久记忆“的革命性方案
数据库·人工智能·redis
niceffking3 小时前
C++内部类的ISO约定和语法细节
开发语言·c++
wjs20243 小时前
C# 常量
开发语言