上一篇文章中, 我介绍了企业库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. Using CORS(译)

    原文地址:https://docs.webplatform.org/wiki/tutorials/using_cors 总结 一篇对"Cross Origin Resource Sharin ...

  2. bzoj 4070 [Apio2015]雅加达的摩天楼 Dijkstra+建图

    [Apio2015]雅加达的摩天楼 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 644  Solved: 238[Submit][Status][D ...

  3. UBOOT启动内核过程

    1.摘要 (1).启动4步骤第一步:将内核搬移到DDR中第二步:校验内核格式.CRC等第三步:准备传参第四步:跳转执行内核(2).涉及到的主要函数是:do_bootm和do_bootm_linux(3 ...

  4. 2015/8/26 Python基础(1):基本规则及赋值

    Python有如下的基本规则: #后表示注释 \n是行分隔符 \是继续上一行,将过长语句分开 :分号将两个语句连接在一行中 :冒号将代码头和体分开 代码块用缩进块的方式体现 不同缩进深度分隔不同的代码 ...

  5. Tomcat报错java.lang.ClassNotFoundException: 2localhost.org.apache.juli.FileHandler

    Can't load log handler "1catalina.org.apache.juli.FileHandler" java.lang.ClassNotFoundExce ...

  6. 【STSRM10】dp只会看规律

    [算法]区间DP [题意]平面上有n个点(xi,yi),用最少个数的底边在x轴上且面积为S的矩形覆盖这些点(在边界上也算覆盖),n<=100. [题解]随机大数据下,贪心几乎没有错误,贪心出奇迹 ...

  7. Mac 上真机调试cocos2d-x-3.16的test程序

    文章比较长,一个算是新手又不是新手的程序员的解决过程. 一 xcode中打开项目 首先,下载完成cocos2d-x-3.16之后,解压,然后在根目录build目录下双击cocos2d_tests.xc ...

  8. No 'Access-Control-Allow-Origin' Ajax跨域访问解决方案

    No 'Access-Control-Allow-Origin' header is present on the requested resource. 当使用ajax访问远程服务器时,请求失败,浏 ...

  9. CTF线下赛AWD模式下的生存技巧

    作者:Veneno@Nu1L 稿费:200RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 原文:https://www.anquanke.com/post/id/8467 ...

  10. MVC自定义路由实现URL重写,SEO优化

    //App_Start-RouteConfig.cs public class RouteConfig { public static void RegisterRoutes(RouteCollect ...