ASP.NET MVC5+EF6+EasyUI 后台管理系统(62)-EF链接串加密
系列目录
前言:
这一节提供一个简单的功能,这个功能看似简单,找了一下没找到EF链接数据库串的加密帮助文档,只能自己写了,这样也更加符合自己的加密要求
- 有时候我们发布程序为了避免程序外的SQL链接串明文暴露,需要进行一些加密手段!
- 加密主要分几类:对称加密,非对称加密,散列算法(自己百度脑补,这里不再多说)
- 我这里选择AES 256位的加密,主要加密速度算法快,安全性高,资源消耗低。
- 公司一直在使用AES加密来加密一些小数据量的数据,比较方法和安全
这是我选择加密AES的理由,当然你可以选择其他有名的加密算法,比如MD5,SHA,3DES.(注:大公司应该都是禁止自行写算法的来加解密的)
知识点:
数据的使用跟我们登录流程基本都是一样的,获取加密链接串,然后解密使用
所以我们需要:
- 加密类
- 加密工具
- EF在何处使用链接字符串
1.加密类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
namespace Apps.Common
{
public class AESEncryptHelper
{ /// <summary>
/// 获取密钥
/// </summary>
private static string Key
{
get { return @")O[NB]6,YF}+efcaj{+oESb9d8>Z'e9M"; }
} /// <summary>
/// 获取向量
/// </summary>
private static string IV
{
get { return @"L+\~f4,Ir)b$=pkf"; }
} #region 参数是byte[]类型
/// <summary>
/// AES加密
/// </summary>
/// <param name="Data">被加密的明文</param>
/// <param name="Key">密钥</param>
/// <param name="Vector">向量</param>
/// <returns>密文</returns>
public static Byte[] AESEncrypt(Byte[] Data, String Key, String Vector)
{
Byte[] bKey = new Byte[];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
Byte[] bVector = new Byte[];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
Byte[] Cryptograph = null; // 加密后的密文
Rijndael Aes = Rijndael.Create();
try
{
// 开辟一块内存流
using (MemoryStream Memory = new MemoryStream())
{
// 把内存流对象包装成加密流对象
using (CryptoStream Encryptor = new CryptoStream(Memory,
Aes.CreateEncryptor(bKey, bVector),
CryptoStreamMode.Write))
{
// 明文数据写入加密流
Encryptor.Write(Data, , Data.Length);
Encryptor.FlushFinalBlock(); Cryptograph = Memory.ToArray();
}
}
}
catch
{
Cryptograph = null;
}
return Cryptograph;
} /// <summary>
/// AES解密
/// </summary>
/// <param name="Data">被解密的密文</param>
/// <param name="Key">密钥</param>
/// <param name="Vector">向量</param>
/// <returns>明文</returns>
public static Byte[] AESDecrypt(Byte[] Data, String Key, String Vector)
{
Byte[] bKey = new Byte[];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
Byte[] bVector = new Byte[];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length); Byte[] original = null; // 解密后的明文 Rijndael Aes = Rijndael.Create();
try
{
// 开辟一块内存流,存储密文
using (MemoryStream Memory = new MemoryStream(Data))
{
// 把内存流对象包装成加密流对象
using (CryptoStream Decryptor = new CryptoStream(Memory,
Aes.CreateDecryptor(bKey, bVector),
CryptoStreamMode.Read))
{
// 明文存储区
using (MemoryStream originalMemory = new MemoryStream())
{
Byte[] Buffer = new Byte[];
Int32 readBytes = ;
while ((readBytes = Decryptor.Read(Buffer, , Buffer.Length)) > )
{
originalMemory.Write(Buffer, , readBytes);
} original = originalMemory.ToArray();
}
}
}
}
catch
{
original = null;
}
return original;
} #endregion #region 参数是string类型 /// <summary>
/// AES加密
/// </summary>
/// <param name="plainStr">明文字符串</param>
/// <returns>密文</returns>
public static string AESEncrypt(string plainStr)
{
byte[] bKey = Encoding.UTF8.GetBytes(Key);
byte[] bIV = Encoding.UTF8.GetBytes(IV);
byte[] byteArray = Encoding.UTF8.GetBytes(plainStr); string encrypt = null;
Rijndael aes = Rijndael.Create();
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))
{
cStream.Write(byteArray, , byteArray.Length);
cStream.FlushFinalBlock();
encrypt = Convert.ToBase64String(mStream.ToArray());
}
}
aes.Clear();
return encrypt;
} /// <summary>
/// AES加密
/// </summary>
/// <param name="plainStr">明文字符串</param>
/// <param name="returnNull">加密失败时是否返回 null,false 返回 String.Empty</param>
/// <returns>密文</returns>
public static string AESEncrypt(string plainStr, bool returnNull)
{
string encrypt = AESEncrypt(plainStr);
return returnNull ? encrypt : (encrypt == null ? String.Empty : encrypt);
} /// <summary>
/// AES解密
/// </summary>
/// <param name="encryptStr">密文字符串</param>
/// <returns>明文</returns>
public static string AESDecrypt(string encryptStr)
{
byte[] bKey = Encoding.UTF8.GetBytes(Key);
byte[] bIV = Encoding.UTF8.GetBytes(IV);
byte[] byteArray = Convert.FromBase64String(encryptStr); string decrypt = null;
Rijndael aes = Rijndael.Create();
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write))
{
cStream.Write(byteArray, , byteArray.Length);
cStream.FlushFinalBlock();
decrypt = Encoding.UTF8.GetString(mStream.ToArray());
}
}
aes.Clear();
return decrypt;
} /// <summary>
/// AES解密
/// </summary>
/// <param name="encryptStr">密文字符串</param>
/// <param name="returnNull">解密失败时是否返回 null,false 返回 String.Empty</param>
/// <returns>明文</returns>
public static string AESDecrypt(string encryptStr, bool returnNull)
{
string decrypt = AESDecrypt(encryptStr);
return returnNull ? decrypt : (decrypt == null ? String.Empty : decrypt);
} #endregion #region 256位AES加密算法 /// <summary>
/// 256位AES加密
/// </summary>
/// <param name="toEncrypt"></param>
/// <returns></returns>
public static string Encrypt(string toEncrypt)
{
// 256-AES key
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, , toEncryptArray.Length); return Convert.ToBase64String(resultArray, , resultArray.Length);
} /// <summary>
/// 256位AES解密
/// </summary>
/// <param name="toDecrypt"></param>
/// <returns></returns>
public static string Decrypt(string toDecrypt)
{
// 256-AES key
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, , toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray);
} #endregion
}
}
AESEncryptHelper.cs
网上一抓一大把,自己搜索想要的加密类啦!
2.加密工具
加密工具这个网上抓不到,需要自己结合加密类来开发,这个不用我带领大伙来开发吧,好吧
新建一个WinFrom程序,命名Apps.EncryptHelper,引用你加密类的所在的类库,或者直接放到Apps.EncryptHelper下就可以

从工具栏拉取2个TextBox和2个Button排版好,基本页面就做完了,最后分别双击两个按钮进入事件实现代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Apps.Common;
namespace Apps.EncryptHelper
{
public partial class Encrypt : Form
{
public Encrypt()
{
InitializeComponent();
}
//加密
private void btnEncrypt_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtSourceText.Text))
{
MessageBox.Show("没数据加毛密-_-!");
return;
}
else
{
txtResultText.Text = AESEncryptHelper.Encrypt(txtSourceText.Text);
}
}
//解密
private void btnDecrypt_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtSourceText.Text))
{
MessageBox.Show("没数据解毛密-_-!");
return;
}
else if (!IsBase64Formatted(txtSourceText.Text))
{
MessageBox.Show("别逗了,我只认识被我加过密的?");
return;
}
else
{
txtResultText.Text = AESEncryptHelper.Decrypt(txtSourceText.Text);
}
} public static bool IsBase64Formatted(string input)
{
try
{
Convert.FromBase64String(input);
return true;
}
catch
{
return false;
}
}
}
}
几十行代码,解决车房老婆问题!运行....

.
3.结合进EF
这块还是比较容易搞定的
第一:找到web.config的connectionStrings的EF链接串
第二:把修改对应Key串的Value
<connectionStrings>
<add name="DBContainer" connectionString="ka7ocMA8nEYPjbQYUlVwbsmTeIdxKGE+ZfXAu3/0eMhVRP+iN+9ECpY/lItoY9vfZVDA9EVgmMzH/8Z0rxRIhGPRhVMFWliBuJ9RDGtHbqRY02voyLbrZ7IiXRnXyhlLFsvgj23KXnHl8J6jxB1QNsmuUxPlqnD6HP9y5RQq2EJ//OT+uKqhVC1qUqVzdY+XR6HX/O5jGk6kJGk3Nk83qo09eBOundO7OdxQG9SXPUYNyZjhyx9YV2/1UbghuxHrxHrAuxiE4mJLqH/rusjAy8d3LS/ROiiBszSY+I400Ce4NigDwZaG679yvBKBQ5pg" providerName="System.Data.EntityClient" />
</connectionStrings>
第三:找到EF读取串的地方

这里必须读取解密后发的字符串,所以我们再写一个方法来获取解密后的字符串ConfigPara
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Apps.Common
{
public class ConfigPara
{
public static string EFDBConnection {
get {
string connection = System.Configuration.ConfigurationManager.ConnectionStrings["DBContainer"].ConnectionString;
return AESEncryptHelper.Decrypt(connection);
}
}
}
}

注意修改后也是没有用的,会回档,因为这个类是根据T4生成的,所以我们必须修改T4

修改对应红框的位置!
搞破坏的,难道你现在还能看懂我的连接串?:-)

ok。实现加密,运行正常

大家赶快把他继承到系统里面!
谢谢大家!
ASP.NET MVC5+EF6+EasyUI 后台管理系统(62)-EF链接串加密的更多相关文章
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理 http://ww ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入
系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试
1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级
系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构
系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析
系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控
系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox
系列目录 https://yunpan.cn/cZVeSJ33XSHKZ 访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航
系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...
随机推荐
- C# - 值类型、引用类型&走出误区,容易错误的说法
1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...
- SQL数据库之DQL
初来乍到,我是一个Java行业的小学生,刚学半年. 今天老师讲了数据库的操作语句,在这里与大家分享一下我学到的知识吧,要是有不足的地方麻烦大家指出来,共同进步,共同提高! 1.数据库中的各种符号 %: ...
- Intellij idea添加单元测试工具
1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- PHP代码优化
1 代码优化 1 尽量静态化 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍. 当然了,这个测试方法需要在十万级以上次执行,效果才明显. 其实静态方法和 ...
- Java实现多线程断点下载(下载过程中可以暂停)
线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...
- 电脑新建svn仓库
步骤1:安转svg: 注意事项: 安装的时候选择:Modify 安装到以下图片的步骤时: 黄色区域选择: 步骤2:新建svn仓库文件夹(本教程例子:D:\svn-5gpos),选择文件夹右键,点击下图 ...
- 如何编译Zookeeper源码
1. 安装Ant Ant下载地址:http://ant.apache.org/bindownload.cgi 解压即可. 2. 下载Zookeeper源码包 https://github.com/ap ...
- Centos 6.6 下搭建php5.2.17+Zend Optimizer3.3.9+Jexus环境
(为何安装php5.2.17这个版本 因为phpweb这个程序用到了Zend Optimizer3.3.9 这个东东已经停止更新了 最高支持5.2版本的php 所以就有了一晚上填坑的自己和总结了这篇文 ...
- Windows 7 上安装Visual Studio 2015 失败解决方案
安装之前先要看看自己的系统支不支持,具体的可以看:https://www.visualstudio.com/en-us/visual-studio-2015-system-requirements-v ...