系列目录

前言:

  这一节提供一个简单的功能,这个功能看似简单,找了一下没找到EF链接数据库串的加密帮助文档,只能自己写了,这样也更加符合自己的加密要求

  • 有时候我们发布程序为了避免程序外的SQL链接串明文暴露,需要进行一些加密手段!
  • 加密主要分几类:对称加密,非对称加密,散列算法(自己百度脑补,这里不再多说)
  • 我这里选择AES 256位的加密,主要加密速度算法快,安全性高,资源消耗低。
  • 公司一直在使用AES加密来加密一些小数据量的数据,比较方法和安全

  这是我选择加密AES的理由,当然你可以选择其他有名的加密算法,比如MD5,SHA,3DES.(注:大公司应该都是禁止自行写算法的来加解密的)

知识点:

 数据的使用跟我们登录流程基本都是一样的,获取加密链接串,然后解密使用

 所以我们需要:

  1. 加密类
  2. 加密工具
  3. EF在何处使用链接字符串

1.加密类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Security.Cryptography;
  7. using System.IO;
  8. namespace Apps.Common
  9. {
  10. public class AESEncryptHelper
  11. {
  12.  
  13. /// <summary>
  14. /// 获取密钥
  15. /// </summary>
  16. private static string Key
  17. {
  18. get { return @")O[NB]6,YF}+efcaj{+oESb9d8>Z'e9M"; }
  19. }
  20.  
  21. /// <summary>
  22. /// 获取向量
  23. /// </summary>
  24. private static string IV
  25. {
  26. get { return @"L+\~f4,Ir)b$=pkf"; }
  27. }
  28.  
  29. #region 参数是byte[]类型
  30. /// <summary>
  31. /// AES加密
  32. /// </summary>
  33. /// <param name="Data">被加密的明文</param>
  34. /// <param name="Key">密钥</param>
  35. /// <param name="Vector">向量</param>
  36. /// <returns>密文</returns>
  37. public static Byte[] AESEncrypt(Byte[] Data, String Key, String Vector)
  38. {
  39. Byte[] bKey = new Byte[];
  40. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
  41. Byte[] bVector = new Byte[];
  42. Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
  43. Byte[] Cryptograph = null; // 加密后的密文
  44. Rijndael Aes = Rijndael.Create();
  45. try
  46. {
  47. // 开辟一块内存流
  48. using (MemoryStream Memory = new MemoryStream())
  49. {
  50. // 把内存流对象包装成加密流对象
  51. using (CryptoStream Encryptor = new CryptoStream(Memory,
  52. Aes.CreateEncryptor(bKey, bVector),
  53. CryptoStreamMode.Write))
  54. {
  55. // 明文数据写入加密流
  56. Encryptor.Write(Data, , Data.Length);
  57. Encryptor.FlushFinalBlock();
  58.  
  59. Cryptograph = Memory.ToArray();
  60. }
  61. }
  62. }
  63. catch
  64. {
  65. Cryptograph = null;
  66. }
  67. return Cryptograph;
  68. }
  69.  
  70. /// <summary>
  71. /// AES解密
  72. /// </summary>
  73. /// <param name="Data">被解密的密文</param>
  74. /// <param name="Key">密钥</param>
  75. /// <param name="Vector">向量</param>
  76. /// <returns>明文</returns>
  77. public static Byte[] AESDecrypt(Byte[] Data, String Key, String Vector)
  78. {
  79. Byte[] bKey = new Byte[];
  80. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
  81. Byte[] bVector = new Byte[];
  82. Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
  83.  
  84. Byte[] original = null; // 解密后的明文
  85.  
  86. Rijndael Aes = Rijndael.Create();
  87. try
  88. {
  89. // 开辟一块内存流,存储密文
  90. using (MemoryStream Memory = new MemoryStream(Data))
  91. {
  92. // 把内存流对象包装成加密流对象
  93. using (CryptoStream Decryptor = new CryptoStream(Memory,
  94. Aes.CreateDecryptor(bKey, bVector),
  95. CryptoStreamMode.Read))
  96. {
  97. // 明文存储区
  98. using (MemoryStream originalMemory = new MemoryStream())
  99. {
  100. Byte[] Buffer = new Byte[];
  101. Int32 readBytes = ;
  102. while ((readBytes = Decryptor.Read(Buffer, , Buffer.Length)) > )
  103. {
  104. originalMemory.Write(Buffer, , readBytes);
  105. }
  106.  
  107. original = originalMemory.ToArray();
  108. }
  109. }
  110. }
  111. }
  112. catch
  113. {
  114. original = null;
  115. }
  116. return original;
  117. }
  118.  
  119. #endregion
  120.  
  121. #region 参数是string类型
  122.  
  123. /// <summary>
  124. /// AES加密
  125. /// </summary>
  126. /// <param name="plainStr">明文字符串</param>
  127. /// <returns>密文</returns>
  128. public static string AESEncrypt(string plainStr)
  129. {
  130. byte[] bKey = Encoding.UTF8.GetBytes(Key);
  131. byte[] bIV = Encoding.UTF8.GetBytes(IV);
  132. byte[] byteArray = Encoding.UTF8.GetBytes(plainStr);
  133.  
  134. string encrypt = null;
  135. Rijndael aes = Rijndael.Create();
  136. using (MemoryStream mStream = new MemoryStream())
  137. {
  138. using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))
  139. {
  140. cStream.Write(byteArray, , byteArray.Length);
  141. cStream.FlushFinalBlock();
  142. encrypt = Convert.ToBase64String(mStream.ToArray());
  143. }
  144. }
  145. aes.Clear();
  146. return encrypt;
  147. }
  148.  
  149. /// <summary>
  150. /// AES加密
  151. /// </summary>
  152. /// <param name="plainStr">明文字符串</param>
  153. /// <param name="returnNull">加密失败时是否返回 null,false 返回 String.Empty</param>
  154. /// <returns>密文</returns>
  155. public static string AESEncrypt(string plainStr, bool returnNull)
  156. {
  157. string encrypt = AESEncrypt(plainStr);
  158. return returnNull ? encrypt : (encrypt == null ? String.Empty : encrypt);
  159. }
  160.  
  161. /// <summary>
  162. /// AES解密
  163. /// </summary>
  164. /// <param name="encryptStr">密文字符串</param>
  165. /// <returns>明文</returns>
  166. public static string AESDecrypt(string encryptStr)
  167. {
  168. byte[] bKey = Encoding.UTF8.GetBytes(Key);
  169. byte[] bIV = Encoding.UTF8.GetBytes(IV);
  170. byte[] byteArray = Convert.FromBase64String(encryptStr);
  171.  
  172. string decrypt = null;
  173. Rijndael aes = Rijndael.Create();
  174. using (MemoryStream mStream = new MemoryStream())
  175. {
  176. using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write))
  177. {
  178. cStream.Write(byteArray, , byteArray.Length);
  179. cStream.FlushFinalBlock();
  180. decrypt = Encoding.UTF8.GetString(mStream.ToArray());
  181. }
  182. }
  183. aes.Clear();
  184. return decrypt;
  185. }
  186.  
  187. /// <summary>
  188. /// AES解密
  189. /// </summary>
  190. /// <param name="encryptStr">密文字符串</param>
  191. /// <param name="returnNull">解密失败时是否返回 null,false 返回 String.Empty</param>
  192. /// <returns>明文</returns>
  193. public static string AESDecrypt(string encryptStr, bool returnNull)
  194. {
  195. string decrypt = AESDecrypt(encryptStr);
  196. return returnNull ? decrypt : (decrypt == null ? String.Empty : decrypt);
  197. }
  198.  
  199. #endregion
  200.  
  201. #region 256位AES加密算法
  202.  
  203. /// <summary>
  204. /// 256位AES加密
  205. /// </summary>
  206. /// <param name="toEncrypt"></param>
  207. /// <returns></returns>
  208. public static string Encrypt(string toEncrypt)
  209. {
  210. // 256-AES key
  211. byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
  212. byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
  213.  
  214. RijndaelManaged rDel = new RijndaelManaged();
  215. rDel.Key = keyArray;
  216. rDel.Mode = CipherMode.ECB;
  217. rDel.Padding = PaddingMode.PKCS7;
  218.  
  219. ICryptoTransform cTransform = rDel.CreateEncryptor();
  220. byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, , toEncryptArray.Length);
  221.  
  222. return Convert.ToBase64String(resultArray, , resultArray.Length);
  223. }
  224.  
  225. /// <summary>
  226. /// 256位AES解密
  227. /// </summary>
  228. /// <param name="toDecrypt"></param>
  229. /// <returns></returns>
  230. public static string Decrypt(string toDecrypt)
  231. {
  232. // 256-AES key
  233. byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
  234. byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
  235.  
  236. RijndaelManaged rDel = new RijndaelManaged();
  237. rDel.Key = keyArray;
  238. rDel.Mode = CipherMode.ECB;
  239. rDel.Padding = PaddingMode.PKCS7;
  240.  
  241. ICryptoTransform cTransform = rDel.CreateDecryptor();
  242. byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, , toEncryptArray.Length);
  243.  
  244. return UTF8Encoding.UTF8.GetString(resultArray);
  245. }
  246.  
  247. #endregion
  248. }
  249. }

AESEncryptHelper.cs

网上一抓一大把,自己搜索想要的加密类啦!

2.加密工具

加密工具这个网上抓不到,需要自己结合加密类来开发,这个不用我带领大伙来开发吧,好吧

新建一个WinFrom程序,命名Apps.EncryptHelper,引用你加密类的所在的类库,或者直接放到Apps.EncryptHelper下就可以

从工具栏拉取2个TextBox和2个Button排版好,基本页面就做完了,最后分别双击两个按钮进入事件实现代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using Apps.Common;
  11. namespace Apps.EncryptHelper
  12. {
  13. public partial class Encrypt : Form
  14. {
  15. public Encrypt()
  16. {
  17. InitializeComponent();
  18. }
  19. //加密
  20. private void btnEncrypt_Click(object sender, EventArgs e)
  21. {
  22. if (string.IsNullOrEmpty(txtSourceText.Text))
  23. {
  24. MessageBox.Show("没数据加毛密-_-!");
  25. return;
  26. }
  27. else
  28. {
  29. txtResultText.Text = AESEncryptHelper.Encrypt(txtSourceText.Text);
  30. }
  31. }
  32. //解密
  33. private void btnDecrypt_Click(object sender, EventArgs e)
  34. {
  35. if (string.IsNullOrEmpty(txtSourceText.Text))
  36. {
  37. MessageBox.Show("没数据解毛密-_-!");
  38. return;
  39. }
  40. else if (!IsBase64Formatted(txtSourceText.Text))
  41. {
  42. MessageBox.Show("别逗了,我只认识被我加过密的?");
  43. return;
  44. }
  45. else
  46. {
  47. txtResultText.Text = AESEncryptHelper.Decrypt(txtSourceText.Text);
  48. }
  49. }
  50.  
  51. public static bool IsBase64Formatted(string input)
  52. {
  53. try
  54. {
  55. Convert.FromBase64String(input);
  56. return true;
  57. }
  58. catch
  59. {
  60. return false;
  61. }
  62. }
  63. }
  64. }

几十行代码,解决车房老婆问题!运行....

.

3.结合进EF

这块还是比较容易搞定的

第一:找到web.config的connectionStrings的EF链接串

第二:把修改对应Key串的Value

  1. <connectionStrings>
  2. <add name="DBContainer" connectionString="ka7ocMA8nEYPjbQYUlVwbsmTeIdxKGE+ZfXAu3/0eMhVRP+iN+9ECpY/lItoY9vfZVDA9EVgmMzH/8Z0rxRIhGPRhVMFWliBuJ9RDGtHbqRY02voyLbrZ7IiXRnXyhlLFsvgj23KXnHl8J6jxB1QNsmuUxPlqnD6HP9y5RQq2EJ//OT+uKqhVC1qUqVzdY+XR6HX/O5jGk6kJGk3Nk83qo09eBOundO7OdxQG9SXPUYNyZjhyx9YV2/1UbghuxHrxHrAuxiE4mJLqH/rusjAy8d3LS/ROiiBszSY+I400Ce4NigDwZaG679yvBKBQ5pg" providerName="System.Data.EntityClient" />
  3. </connectionStrings>

第三:找到EF读取串的地方

这里必须读取解密后发的字符串,所以我们再写一个方法来获取解密后的字符串ConfigPara

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace Apps.Common
  8. {
  9. public class ConfigPara
  10. {
  11. public static string EFDBConnection {
  12. get {
  13. string connection = System.Configuration.ConfigurationManager.ConnectionStrings["DBContainer"].ConnectionString;
  14. return AESEncryptHelper.Decrypt(connection);
  15. }
  16. }
  17. }
  18. }

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

修改对应红框的位置!

搞破坏的,难道你现在还能看懂我的连接串?:-)

ok。实现加密,运行正常

大家赶快把他继承到系统里面!

谢谢大家!

ASP.NET MVC5+EF6+EasyUI 后台管理系统(62)-EF链接串加密的更多相关文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理   http://ww ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入

    系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

    系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析

    系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox

    系列目录 https://yunpan.cn/cZVeSJ33XSHKZ  访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航

    系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...

随机推荐

  1. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  2. 让 windows 下的命令行程序 cmd.exe 用起来更顺手

    在 Windows 下使用 Larave 框架做开发,从 Composer 到 artisan 总是避免不了和 cmd.exe 打交道,系统默认的命令行界面却是不怎么好看,且每行显示的字符数是做了限制 ...

  3. Vertica 数据库知识汇总篇

    Vertica 数据库知识汇总篇(更新中..) 1.Vertica 集群软件部署,各节点硬件性能测试 2.Vertica 创建数据库,创建业务用户测试 3.Vertica 数据库参数调整,资源池分配 ...

  4. RIFF和WAVE音频文件格式

    RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...

  5. Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误——SHH框架

    SHH框架工程,Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误 1.查看配置文件web.xml中是否配置.or ...

  6. Spring获取ApplicationContext

    在Spring+Struts+Hibernate中,有时需要使用到Spring上下文.项目启动时,会自动根据applicationContext配置文件初始化上下文,可以使用ApplicationCo ...

  7. 【Java每日一题】20170106

    20170105问题解析请点击今日问题下方的"[Java每日一题]20170106"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...

  8. BPM生产安全管理解决方案分享

    一.方案概述生产安全管理是企业生产管理的重要组成部分,组织实施好企业安全管理规划.指导.检查和决策,保证生产处于最佳安全状态是安全管理的重要内容和职责.H3 BPM企业生产安全管理解决方案是一套专门为 ...

  9. IT雇员及外包商选择:人品第一

    最近,苹果iOS操作系统和智能手机爆出了一个奇葩故障,在播放特定一段五秒钟的视频时能导致手机死机.唯一的解决办法是按住电源键和Home按键进行手机的重启. 第十八届中国国际高新技术成果交易会在深圳举办 ...

  10. mysql 赋予用户权限

    # 赋予权限MySQL> grant 权限参数 on 数据库名称.表名称 to 用户名@用户地址 identified by '用户密码'; # 立即生效权限MySQL> flush pr ...