微软企业库5.0 学习之路——第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—下篇
在上一篇文章中, 我介绍了企业库Cryptographer模块的一些重要类,同时介绍了企业库Cryptographer模块为我们提供的扩展接口,今天我就要根据这些 接口来进行扩展开发,实现2个加密解密方法(离散加密和对称性加密),分别实现自接口IHashProvider和接口 ISymmetricCryptoProvider。
首先来看下离散加密——CustomHashCryptography,具体代码如下:
using System;
using System.Collections.Generic;
//构造函数中接受参数的类型NameValueCollection所在命名空间
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Security.Cryptography; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;//用于企业库配置工具绑定
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Configuration; namespace EntLibStudy.Helper
{
[ConfigurationElementType(typeof(CustomHashProviderData))]
public class CustomHashCryptography : IHashProvider
{
/// <summary>
/// 构造函数,此处不可省略,否则会导致异常
/// </summary>
/// <param name="attributes">配置文件中所配置的参数</param>
public CustomHashCryptography(NameValueCollection attributes)
{
}
/// <summary>
/// 比较数据和已加密数据是否相等
/// </summary>
/// <param name="plaintext">未加密数据</param>
/// <param name="hashedtext">已加密数据</param>
/// <returns>是否相等</returns>
public bool CompareHash(byte[] plaintext, byte[] hashedtext)
{
var tmpHashText = CreateHash(plaintext);
if (tmpHashText == null || hashedtext == null)
return false;
if (tmpHashText.Length != hashedtext.Length)
return false;
for (int i = ; i < tmpHashText.Length; i++)
{
if (tmpHashText[i] != hashedtext[i])
return false;
}
return true;
}
/// <summary>
/// 创建加密
/// </summary>
/// <param name="plaintext">待加密数据</param>
/// <returns>加密后数据</returns>
public byte[] CreateHash(byte[] plaintext)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
return md5.ComputeHash(plaintext);
}
}
}
这段代码主要就是实现一个离散加密,不过还是有几点需要注意:
1、在实现接口IHashProvider的基础上,为了能让这个自定义加密可以在企业库的配置工具里调用到需要为类加上一个特性: [ConfigurationElementType(typeof(CustomHashProviderData))],这个特性所在的命名空间为:using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;。
2、这个自定义加密必须包含一个构造函数,其参数的类型是NameValueCollection,这个参数是从配置文件中获取指定的配置属性,见下图:
![]()
注意:这个NameValueCollection类型,需要引用命名空间:using System.Collections.Specialized;
如果没有这个构造函数,将会引发异常:
Type does not provide a constructor taking a single parameter type of NameValueCollection
3、方法CompareHash、CreateHash,接收和返回的类型都是字节数组。
接下来看下对称加密CustomSymmetricCryptography ,具体代码如下:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Configuration; namespace EntLibStudy.Helper
{
[ConfigurationElementType(typeof(CustomSymmetricCryptoProviderData))]
public class CustomSymmetricCryptography : ISymmetricCryptoProvider
{
private string encryptKey="";
public CustomSymmetricCryptography(NameValueCollection attributes)
{
//从配置文件中获取key,如不存在则指定默认key
encryptKey = String.IsNullOrEmpty(attributes["key"]) ? "kyo-yo" : attributes["key"];
} //默认密钥向量
private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; /// <summary>
/// 加密
/// </summary>
/// <param name="ciphertext">待加密数据</param>
/// <returns>加密后数据</returns>
public byte[] Decrypt(byte[] ciphertext)
{
if (encryptKey.Length > )
{
encryptKey = encryptKey.Substring(, );
}
encryptKey = encryptKey.PadRight(, ' ');
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey);
byte[] rgbIV = Keys;
byte[] inputByteArray = ciphertext;
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, , inputByteArray.Length);
cStream.FlushFinalBlock();
return mStream.ToArray();
} /// <summary>
/// 解密
/// </summary>
/// <param name="plaintext">加密数据</param>
/// <returns>解密后数据</returns>
public byte[] Encrypt(byte[] plaintext)
{
if (encryptKey.Length > )
{
encryptKey = encryptKey.Substring(, );
}
encryptKey = encryptKey.PadRight(, ' ');
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(, ));
byte[] rgbIV = Keys;
byte[] inputByteArray = plaintext;
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, , inputByteArray.Length);
cStream.FlushFinalBlock();
return mStream.ToArray();
}
}
}
这个对称性加密的注意点基本和离散加密一样,但是这边的对称加密我引入了一个加密key,这个key是从配置文件中获取的。
第三点:在项目中应用自定义接口
在上面已经扩展好了2个加密方式,现在就要在实际的项目中运用这2个加密方式,首先打开企业库的配置工具,添加Cryptographer模块,然 后在Hash Providers和ISymmetric Cryptograhpy Providers下分别添加刚才定义好的2个加密方式。
注意:添加的自定义加密方式必须放在项目的根目录下,如果放在项目下的文件夹下,如:Helper\Extension下,从企业库的配置文件中将无法找到自定义的加密方式,见下图:
在添加完配置后就可以在web.config看到以下配置信息:
<securityCryptographyConfiguration>
<hashProviders>
<add type="EntLibStudy.Helper.CustomHashCryptography, EntLibStudy.Helper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="CustomHashCryptography" />
</hashProviders>
<symmetricCryptoProviders>
<add key="kyo-yo" type="EntLibStudy.Helper.CustomSymmetricCryptography, EntLibStudy.Helper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="CustomSymmetricCryptography" />
</symmetricCryptoProviders>
</securityCryptographyConfiguration>
配置完后,我又在Helper.Utils类中添加了几个加密解密方法的封装,用于表示层调用(主要是根据配置实例名和待加密数据获取加密数据),代码如下:
/// <summary>
/// 根据配置进行加密
/// </summary>
/// <param name="instance">配置实例名</param>
/// <param name="encryptString">待加密字符串</param>
/// <returns>加密后字符串</returns>
public static string Encode(string instance, string encryptString)
{
return Cryptographer.EncryptSymmetric(instance, encryptString);
}
/// <summary>
/// 根据配置进行解密
/// </summary>
/// <param name="instance">配置实例名</param>
/// <param name="decryptString">待解密字符串</param>
/// <returns>解密后字符串</returns>
public static string Decode(string instance, string decryptString)
{
return Cryptographer.DecryptSymmetric(instance, decryptString);
}
/// <summary>
/// 根据配置进行离散加密
/// </summary>
/// <param name="instance">配置实例名</param>
/// <param name="plaintString">待加密字符串</param>
/// <returns>解密后字符串</returns>
public static string CreateHash(string instance, string plaintString)
{
return Cryptographer.CreateHash(instance, plaintString);
}
/// <summary>
/// 比较离散值是否相等
/// </summary>
/// <param name="instance">配置实例名</param>
/// <param name="plaintString">未加密字符串</param>
/// <param name="hashedString">已加密字符串</param>
/// <returns>是否相等</returns>
public static bool CompareHash(string instance,string plaintString, string hashedString)
{
return Cryptographer.CompareHash(instance, plaintString, hashedString);
}
接下来就是主要的项目应用了,在以前的代码中,例如学员的密码我是以明文的形式保存进数据库的,这显示是很不安全的,现在我就要替换这块代码,通过调用Utils.CreateHash方法加密录入的密码:
/// <summary>
/// 获取已验证的学员对象
/// </summary>
/// <param name="student">学员对象</param>
/// <returns>是否验证成功</returns>
private bool GetValidatedStudent(ref Model.Student student)
{
if (student == null)
{
student = new Model.Student();
}
student.ClassId = Convert.ToInt32(ddlClass.SelectedValue);
student.Sid = txtSid.Text.Trim();
student.Password = Helper.Utils.CreateHash("CustomHashCryptography", txtPwd.Text.Trim());
student.Name = txtName.Text.Trim();
student.Sex = Convert.ToInt32(rblSex.SelectedValue);
student.Birthday = DateTime.Parse(txtBirthday.Text.Trim()); return student.IsValid();
}
以上就是本文的主要内容,本文主要介绍了:
1、如何通过企业库Cryptographer模块给出的接口进行扩展加密方法,以及扩展时需要注意的问题
2、在项目中使用已经扩展好的加密方法。
本文内容比较简单,如发现问题欢迎指出,谢谢大家!
源代码下载:点我下载
注意:
1、MSSQL数据库在DataBase目录下(需要自行附加数据库),SQLite数据库在Web目录的App_Data下,由于考虑到项目的大小,所以每个项目的BIN目录都已经删除,如出现无法生成项目请自行添加相关企业库的DLL。
2、由于微软企业库5.0 学习之路这个系列我是准备以一个小型项目的形式介绍企业库的各模块,所以源代码会根据系列文章的更新而更新,所以源代码不能保证与文章中所贴代码相同。
3、项目开发环境为:VS2010+SQL2005。
4、管理员帐户:admin
密码:admin
微软企业库5.0 学习之路——第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—下篇的更多相关文章
- 微软企业库5.0 学习之路——第八步、使用Configuration Setting模块等多种方式分类管理企业库配置信息
在介绍完企业库几个常用模块后,我今天要对企业库的配置文件进行处理,缘由是我打开web.config想进行一些配置的时候发现web.config已经变的异常的臃肿(大量的企业库配置信息充斥其中),所以决 ...
- 微软企业库5.0 学习之路——第六步、使用Validation模块进行服务器端数据验证
前端时间花了1个多星期的时间写了使用jQuery.Validate进行客户端验证,但是那仅仅是客户端的验证,在开发项目的过程中,客户端的信息永远是不可信的,所以我们还需要在服务器端进行服务器端的验证已 ...
- 微软企业库5.0 学习之路——第四步、使用缓存提高网站的性能(EntLib Caching)
首先先补习下企业库的Caching Application Block的相关知识: 1.四大缓存方式,在Caching Application Block中,主要提供以下四种保存缓存数据的途径,分别是 ...
- 微软企业库5.0 学习之路——第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——下篇
一.独立验证器 我上篇中我将AndCompositeValidator和OrCompositeValidator归为独立验证器,这2个验证器主要是为了第一类验证服务,可以进行多种验证组合在一起进行复杂 ...
- 微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)
今天继续介绍Unity,在上一篇的文章中,我介绍了使用UnityContainer来注册对象之间的关系.注册已存在的对象之间的关系,同时着重介绍 了Unity内置的各种生命周期管理器的使用方法,今天则 ...
- [EntLib]微软企业库5.0 学习之路——第一步、基本入门
话说在大学的时候帮老师做项目的时候就已经接触过企业库了但是当初一直没明白为什么要用这个,只觉得好麻烦啊,竟然有那么多的乱七八糟的配置(原来我不知道有配置工具可以进行配置,请原谅我的小白). 直到去年在 ...
- 微软企业库5.0 学习之路——第二步、使用VS2010+Data Access模块建立多数据库项目
现在我就开始进入学习之路的第二步——Data Access模块,这个模块是企业库中被使用频率最高的模块,它很好的封装了数据库操作应用,为我们进行多数据库系统开发提供了便利,只需更改配置文件就 可以很快 ...
- 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录
在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...
- 微软企业库5.0 学习之路——扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]
这篇文章是我在patterns & practices看到的一篇有关EntLib5.0的文章,主要介绍了EntLib5.0的这次的架构变化由来,觉得很不错,大家可以看一下! 在过去几年中,依赖 ...
随机推荐
- android 自定义控件---圆形方向盘
在做Android平台开发的时候,经常会遇到安卓原生控件无法满足需求的情况,安卓允许开发者去继承已经存在的控件或者实现你自己的控件. 先来看一下效果图 采用直接集成View类,重写onDrow方法绘制 ...
- HDU 2686 / NYOJ 61 DP
传纸条(一) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...
- SSH内存泄露及Spring Quartz问题
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://www.blogbus.com/anoxia-logs/34360203.html 问题的起因: 为客户开发了一个系统权 ...
- ConvexScore
题目描述 You are given N points (xi,yi) located on a two-dimensional plane. Consider a subset S of the N ...
- [洛谷P3763] [TJOI2017]DNA
洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...
- SQL Server Compact/SQLite Toolbox
如果你的vs2013 无法打开 .sdf 数据库文件. 那么 SQL Server Compact/SQLite Toolbox,可以帮助你. 下载安装后, vs2013->tools-> ...
- 省队集训 Day3 杨北大
[题目大意] 给出平面上$n$个点$(x_i, y_i)$,请选择一个不在这$n$个点之内的点$(X, Y)$,定义$(X, Y)$的价值为往上下左右四个方向射出去直线,经过$n$个点中的数量的最小值 ...
- 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring
[题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...
- bzoj 2258 splay
类似于1014,用splay维护这个序列,维护每个节点为根的子树的hash值,对于一个询问二分答案判断就行了. 反思:询问的时候因为是原序列的x,y,所以开始的时候直接splay(x-1)了,后来发现 ...
- ms17-010 攻击win7漏洞复现
只是为了好玩重新写一篇.利用还是很简单的. 将下载下来的rb放置在:/usr/share/metasploit-framework/modules/exploits/windows/smb/ 目录下 ...