微软企业库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的这次的架构变化由来,觉得很不错,大家可以看一下! 在过去几年中,依赖 ...
随机推荐
- HDU3308 线段树(区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU1384 差分约束
Intervals Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- Hive分组后取组内排名方法row_number
今天遇到这样一个需求场景,要取出 每一种分类(a,b组合分类) 符合条件的日期(字段c) 距离现在最近的10个日期 的数据 首先想到的是用sql筛选出符合某种条件的所有数据,这样的事情很简单 然后用脚 ...
- http中有关缓存相关的几个字段
转载自:http://blog.csdn.net/lifeibo/article/details/5979572 Expires.Cache-Control.Last-Modified. ETag是R ...
- [Luogu 2596] ZJOI2006 书架
[Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...
- 前端表单序列化为json串,以及构造json数组、json串
var parm={ username:"zhangsan", age:24, email:"352400260@qq.com" }; console.log( ...
- VM 脚本回快照和开关机
#Import PowerCLI*Get-Module -ListAvailable PowerCLI* | Import-Module #Resolve login issueSet-PowerCL ...
- 【CodeForces】835D Palindromic characteristics
[题意]给你一个串,让你求出k阶回文子串有多少个.k从1到n.k阶子串的定义是:子串本身是回文串,而且它的左半部分也是回文串. [算法]区间DP [题解]涉及回文问题的区间DP都可以用类似的写法,就是 ...
- 彻底解决_OBJC_CLASS_$_某文件名", referenced from:问题
最近在使用静态库时,总是出现这个问题.下面总结一下我得解决方法: 1. .m文件没有导入 在Build Phases里的Compile Sources 中添加报错的文件 2. .framewor ...
- Spring4+SpringMVC+MyBatis整合思路(山东数漫江湖)
1.Spring框架的搭建 这个很简单,只需要web容器中注册org.springframework.web.context.ContextLoaderListener,并指定spring加载配置文件 ...