上一篇文章中, 我介绍了企业库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加密模块简单分析、自定义加密接口及使用—下篇的更多相关文章

  1. 微软企业库5.0 学习之路——第八步、使用Configuration Setting模块等多种方式分类管理企业库配置信息

    在介绍完企业库几个常用模块后,我今天要对企业库的配置文件进行处理,缘由是我打开web.config想进行一些配置的时候发现web.config已经变的异常的臃肿(大量的企业库配置信息充斥其中),所以决 ...

  2. 微软企业库5.0 学习之路——第六步、使用Validation模块进行服务器端数据验证

    前端时间花了1个多星期的时间写了使用jQuery.Validate进行客户端验证,但是那仅仅是客户端的验证,在开发项目的过程中,客户端的信息永远是不可信的,所以我们还需要在服务器端进行服务器端的验证已 ...

  3. 微软企业库5.0 学习之路——第四步、使用缓存提高网站的性能(EntLib Caching)

    首先先补习下企业库的Caching Application Block的相关知识: 1.四大缓存方式,在Caching Application Block中,主要提供以下四种保存缓存数据的途径,分别是 ...

  4. 微软企业库5.0 学习之路——第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——下篇

    一.独立验证器 我上篇中我将AndCompositeValidator和OrCompositeValidator归为独立验证器,这2个验证器主要是为了第一类验证服务,可以进行多种验证组合在一起进行复杂 ...

  5. 微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)

    今天继续介绍Unity,在上一篇的文章中,我介绍了使用UnityContainer来注册对象之间的关系.注册已存在的对象之间的关系,同时着重介绍 了Unity内置的各种生命周期管理器的使用方法,今天则 ...

  6. [EntLib]微软企业库5.0 学习之路——第一步、基本入门

    话说在大学的时候帮老师做项目的时候就已经接触过企业库了但是当初一直没明白为什么要用这个,只觉得好麻烦啊,竟然有那么多的乱七八糟的配置(原来我不知道有配置工具可以进行配置,请原谅我的小白). 直到去年在 ...

  7. 微软企业库5.0 学习之路——第二步、使用VS2010+Data Access模块建立多数据库项目

    现在我就开始进入学习之路的第二步——Data Access模块,这个模块是企业库中被使用频率最高的模块,它很好的封装了数据库操作应用,为我们进行多数据库系统开发提供了便利,只需更改配置文件就 可以很快 ...

  8. 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

    在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...

  9. 微软企业库5.0 学习之路——扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]

    这篇文章是我在patterns & practices看到的一篇有关EntLib5.0的文章,主要介绍了EntLib5.0的这次的架构变化由来,觉得很不错,大家可以看一下! 在过去几年中,依赖 ...

随机推荐

  1. Human life FZU - 2295 最大权闭合子图(第一次遇到被教育了)

    Xzz is playing a MMORPG "human life". In this game, there are N different skills. Some ski ...

  2. [samba]samba设置指定用户权限

    步骤: 1.在系统中添加用户 批量添加用户和密码的方法(因为samba用户要求必须在系统中存在): for name in a b c d;do useradd $name ; echo " ...

  3. dns随笔(部分转载)

    1.allow-notify allow-notify 定义了一个匹配列表并且只应用于从dns区域(slave zone),比如,这个列表是一个ip列表,它 2. 触发同步的过程 http://www ...

  4. sql获取当前时间

    sql读取系统日期和时间的方法如下:--获取当前日期(如:yyyymmdd) select CONVERT (nvarchar(12),GETDATE(),112) --获取当前日期(如:yyyymm ...

  5. 状压DP的总结

    状压dp的标志 ①数据小 ②通过题目所给出的条件以后得到的特征集合小 一:CF259div2 D: 题目大意:保证b[i]中每个数互质,给出a[i],然后求1~n的abs(a[i]-b[i])最小.a ...

  6. vijos 1313 金明的预算方案 树形DP

    描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天一 ...

  7. [洛谷P2491] [SDOI2011]消防

    洛谷题目链接:[SDOI2011]消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超 ...

  8. Scala环境安装设置

    Scala语言可以安装在任何类UNIX或Windows系统.要安装Scala,必须先安装Java1.5或更高版本安装在计算机上. Windows上安装Scala: 步骤(1):JAVA设置: 首先,必 ...

  9. 超酷算法-BK树

    前几天无意间遇到一个博客,觉得写得挺好的,自己之前的时候有个不好的习惯,那就是遇到了好资源第一反应就是收藏起来然后却很少再看!!这是坏习惯,要改!于是今天就开始通读了,读的第二篇是BK树.觉得有点意思 ...

  10. Robot Framework Change chrome language

    由于open browser的参数只有一个ff_profile_dir,所以不能指定chrome profile. 只能通过python 传递lang这个参数去改变语言. python: from s ...