【asp.net core 系列】12 数据加密算法
0. 前言
这一篇我们将介绍一下.net core 的加密和解密。在Web应用程序中,用户的密码会使用MD5值作为密码数据存储起来。而在其他的情况下,也会使用加密和解密的功能。
常见的加密算法分为对称加密和非对称加密。所谓的对称加密是指加密密钥和解密密钥是同一个,非对称加密是值加密密钥和解密迷药不同。而我们常应用在保存用户登录密码这个过程中的MD5本质上并不是加密算法,而是一种信息摘要算法。不过MD5尽量保证了每个字符串最后计算出来的值都不一样,所以在密码保存中常用MD5做为保密值。
1. 常见对称加密算法
对称加密算法,简单的说就是加密和解密使用相同的密钥进行运算。对于大多数加密算法,解密和加密是一个互逆的运算。对称加密算法的安全性取决于密钥的长度,密钥越长越安全。当然,不建议使用过长的密钥。
那么,我们来看看常见的对称加密算法有哪些吧,以及C#该如何实现。
1.1 DES 和 DESede 算法
DES算法和DESede算法(又称三重DES算法) 统称DES系列算法。DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。而DESede就是针对同一块数据做三次DES加密。这里就不对原理做过多的介绍了,来看看.net core里如何实现DES加/解密吧。
在Utils项目里,创建目录Security:
在Security目录下,创建DESHelper类:
namespace Utils.Security
{
public class DesHelper
{
}
}
加密解密实现:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Utils.Security
{
public static class DesHelper
{
static DesHelper()
{
DesHandler = DES.Create("DES");
DesHandler.Key = Convert.FromBase64String("L1yzjGB2sI4=");
DesHandler.IV = Convert.FromBase64String("uEcGI4JSAuY=");
}
private static DES DesHandler { get; }
/// <summary>
/// 加密字符
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static string Encrypt(string source)
{
try
{
using (var memStream = new MemoryStream())
using (var cryptStream = new CryptoStream(memStream, DesHandler.CreateEncryptor(DesHandler.Key, DesHandler.IV),
CryptoStreamMode.Write))
{
var bytes = Encoding.UTF8.GetBytes(source);
cryptStream.Write(bytes, 0, bytes.Length);
cryptStream.FlushFinalBlock();
return Convert.ToBase64String(memStream.ToArray());
}
}
catch (Exception e)
{
Console.WriteLine(e);
return null;
}
}
/// <summary>
/// 解密
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static string Decrypt(string source)
{
try
{
using (var mStream = new MemoryStream(Convert.FromBase64String(source)))
using (var cryptoStream =
new CryptoStream(mStream, DesHandler.CreateDecryptor(DesHandler.Key, DesHandler.IV), CryptoStreamMode.Read))
using (var reader = new StreamReader(cryptoStream))
{
return reader.ReadToEnd();
}
}
catch (Exception e)
{
Console.WriteLine(e);
return null;
}
}
}
}
每次调用DesHandler = DES.Create("DES"); 都会重新获得一个DES算法实现实例,这样每次获取的实例中Key、IV这两个属性的值也会发生变化。如果直接使用会出现这次加密的数据下次就没法解密了,为了减少这种情况,所以代码处手动赋值了Key、IV这两个属性。
1.2 AES 加密算法
AES算法(Advanced Encryption Standard)也就是高级数据加密标准算法,是为了解决DES算法中的存在的漏洞而提出的算法标准。现行的AES算法核心是Rijndael算法。当然了,这个不用太过于关心。我们直接看看是如何实现吧:
同样,在Security目录创建一个AesHelper类:
namespace Utils.Security
{
public static class AesHelper
{
}
}
具体的加解密实现:
using System;
using System.IO;
using System.Security.Cryptography;
namespace Utils.Security
{
public static class AesHelper
{
static AesHelper()
{
AesHandler = Aes.Create();
AesHandler.Key = Convert.FromBase64String("lB2BxrJdI4UUjK3KEZyQ0obuSgavB1SYJuAFq9oVw0Y=");
AesHandler.IV = Convert.FromBase64String("6lra6ceX26Fazwj1R4PCOg==");
}
private static Aes AesHandler { get; }
public static string Encrypt(string source)
{
using (var mem = new MemoryStream())
using (var stream = new CryptoStream(mem, AesHandler.CreateEncryptor(AesHandler.Key, AesHandler.IV),
CryptoStreamMode.Write))
{
using (var writer = new StreamWriter(stream))
{
writer.Write(source);
}
return Convert.ToBase64String(mem.ToArray());
}
}
public static string Decrypt(string source)
{
var data = Convert.FromBase64String(source);
using (var mem = new MemoryStream(data))
using (var crypto = new CryptoStream(mem, AesHandler.CreateDecryptor(AesHandler.Key, AesHandler.IV),
CryptoStreamMode.Read))
using (var reader = new StreamReader(crypto))
{
return reader.ReadToEnd();
}
}
}
}
2. 常见非对称加密算法
非对称加密算法,指的是加密密钥和解密密钥并不相同。非对称加密算法的秘钥通常成对出现,分为公开密钥和私有密钥。公开密钥可以以公开的形式发给数据交互方,而不会产生泄密的风险。因为非对称加密算法,无法通过公开密钥推算私有密钥,反之亦然。
通常,非对称加密算法是用公钥进行加密,使用私钥进行解密。
2.1 RSA算法
RSA算法是标准的非对称加密算法,名字来源是三位发明者的姓氏首字母。RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制 。其安全性取决于密钥的长度,1024位的密钥几乎不可能被破解。
同样,在Utils.Security下创建RSAHelper类:
namespace Utils.Security
{
public static class RsaHelper
{
}
}
具体实现:
using System;
using System.Security.Cryptography;
namespace Utils.Security
{
public static class RsaHelper
{
public static RSAParameters PublicKey { get; private set; }
public static RSAParameters PrivateKey { get; private set; }
static RsaHelper()
{
}
public static void InitWindows()
{
var parameters = new CspParameters()
{
KeyContainerName = "RSAHELPER" // 默认的RSA保存密钥的容器名称
};
var handle = new RSACryptoServiceProvider(parameters);
PublicKey = handle.ExportParameters(false);
PrivateKey = handle.ExportParameters(true);
}
public static void ExportKeyPair(string publicKeyXmlString, string privateKeyXmlString)
{
var handle = new RSACryptoServiceProvider();
handle.FromXmlString(privateKeyXmlString);
PrivateKey = handle.ExportParameters(true);
handle.FromXmlString(publicKeyXmlString);
PublicKey = handle.ExportParameters(false);
}
public static byte[] Encrypt(byte[] dataToEncrypt)
{
try
{
byte[] encryptedData;
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
RSA.ImportParameters(PublicKey);
encryptedData = RSA.Encrypt(dataToEncrypt, true);
}
return encryptedData;
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
return null;
}
}
public static byte[] Decrypt(byte[] dataToDecrypt)
{
try
{
byte[] decryptedData;
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(PrivateKey);
decryptedData = rsa.Decrypt(dataToDecrypt, true);
}
return decryptedData;
}
catch (CryptographicException e)
{
Console.WriteLine(e.ToString());
return null;
}
}
}
}
因为RSA的特殊性,需要预先设置好公钥和私钥。C# 支持多种方式导入密钥,这里就不做过多介绍了。
3. 信息摘要算法
这种算法严格意义上并不是加密算法,因为它完全不可逆。也就是说,一旦进行使用该类型算法加密后,无法解密还原出数据。当然了,也正是因为这种特性常常被用来做密码的保存。因为这样可以避免某些人拿到数据库与代码后,可以简单反推出用户的密码。
3.1 MD5算法
最常用的信息摘要算法就是MD5 加密算法,MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
原理不解释,我们看下如何实现,照例现在Security下创建MD5Helper:
namespace Utils.Security
{
public static class Md5Helper
{
}
}
具体实现:
using System.Security.Cryptography;
using System.Text;
namespace Utils.Security
{
public static class Md5Helper
{
private static MD5 Hanlder { get; } = new MD5CryptoServiceProvider();
public static string GetMd5Str(string source)
{
var data = Encoding.UTF8.GetBytes(source);
var security = Hanlder.ComputeHash(data);
var sb = new StringBuilder();
foreach (var b in security)
{
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
}
4 总结
这一篇简单介绍了四种常用的加密算法的实现,当然最常用的就是 MD5,因为这个是大多数系统用来做密码保存的加密算法。
更多内容烦请关注我的博客《高先生小屋》

【asp.net core 系列】12 数据加密算法的更多相关文章
- asp.net core 系列 12 选项 TOptions
一.概述 本章讲的选项模式是对Configuration配置的功能扩展. 讲这篇时有个专用名词叫“选项类(TOptions)” .该选项类作用是指:把选项类中的属性与配置来源中的键关联起来.举个例,假 ...
- 【目录】asp.net core系列篇
随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...
- ASP.NET CORE系列【六】Entity Framework Core 之数据迁移
原文:ASP.NET CORE系列[六]Entity Framework Core 之数据迁移 前言 最近打算用.NET Core写一份简单的后台系统,来练练手 然后又用到了Entity Framew ...
- asp.net core系列 40 Web 应用MVC 介绍与详细示例
一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...
- Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)
Ajax跨域问题及解决方案 目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...
- 【asp.net core 系列】4. 更高更强的路由
0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- asp.net core系列 39 Web 应用Razor 介绍与详细示例
一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor. 这样开发Web包括了MVC框架和Razor框架.对于Razor来说 ...
随机推荐
- 应用4:利用Filter限制用户浏览权限
1. 使用 Filter 完成一个简单的权限模型: 1). 需求: ①. 管理权限 > 查看某人的权限 > 修改某人的权限 ②. 对访问进行权限控制: 有权限则可以访问, 否则提示: 没有 ...
- Rocket - tilelink - fastProperty
https://mp.weixin.qq.com/s/9nikweQUGG5FO3Z8t6feaw 介绍Parameters中定义的fastProperty的实现.(使用最近的新版本,差别不大) ...
- Java实现 蓝桥杯 算法训练 最大的算式
算法训练 最大的算式 时间限制:1.0s 内存限制:256.0MB 问题描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为 ...
- Java实现蓝桥杯分金币
分金币 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币, 最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. 比如,n=4,且4个人 ...
- Java实现 蓝桥杯VIP 算法提高 3-3求圆面积表面积体积
算法提高 3-3求圆面积表面积体积 时间限制:1.0s 内存限制:256.0MB 问题描述 接受用户输⼊的数值,输出以该值为半径的(1)圆面积,(2)球体表面积,(3)球体体积.pi 取值3.1415 ...
- Java实现 LeetCode 149 直线上最多的点数
149. 直线上最多的点数 给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o | ...
- Java实现蓝桥杯G将军
G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军).现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加队员 ...
- Java实现 LeetCode 212 单词搜索 II
public class Find2 { public int[] dx={1,-1,0,0}; public int[] dy={0,0,1,-1}; class Trie{ Trie[] trie ...
- Java实现 洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
输入输出样例 输入 #1 100 5 5 20 9 40 3 10 8 80 6 30 输出 #1 630 import java.util.Arrays; import java.util.Scan ...
- java实现第四届蓝桥杯逆波兰表达式
逆波兰表达式 正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便. 例如:3 + 5 * (2 + 6) - 1 而且,常常需要用括号来改变运算次序. 相反,如果使用逆波兰表 ...