百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

开发者该如何利用 C# 加解密?

liebian365 2025-01-21 19:19 16 浏览 0 评论

作者 | 喵叔

责编 | 刘静

出品 | CSDN(ID:CSDNnews)

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

零、什么是加密解密

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

  1. 发送方可以确定所发送的消息只有预期接收方可以解密,但不保证其他非接收方获得密文,只要保证非接收方获得密文后无法解密即可;

  2. 接收方可以确定消息是谁发送的;

  3. 接收方可以确定消息在传输过程中没有被篡改,也就是说可以验证消息的完整性。

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

  • 不可逆加密;

  • 对称可逆加密;

  • 非堆成可逆加密。

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

不可逆加密

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

  1. 任意长度的输入,经过 MD5 处理后都会输出128位的信息,这个信息称作数字指纹;

  2. 输入不同的信息产生的数字指纹不一样,数字指纹是全球唯一的;

  3. 无法根据数字指纹推导出加密前的信息。MD5 我们经常用在文档防篡改、密码加密、数字签名、网盘秒传。针对这四个方面我下面简单讲解一下:

  4. 文档防篡改

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

  5. 密码加密

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

  6. 数字签名

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

  7. 网盘秒传

    网盘记录文件第一次上传的 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.IsOrEmpty(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. 加密模式

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

  2. 认证模式

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

从上述两种模式的描述中我们可以看到他们存在问题,因此就出现了数字签名,在上述认证模式中加入了散列算法(例如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);
}
}

总结

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

作者简介:朱钢,笔名喵叔,CSDN博客专家,.NET高级开发工程师,7年一线开发经验,参与过电子政务系统和AI客服系统的开发,以及互联网招聘网站的架构设计,目前就职于北京恒创融慧科技发展有限公司,从事企业级安全监控系统的开发。

声明:本文系作者独立观点,不代表CSDN立场。

【END】

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: