[EntLib]微软企业库5.0 学习之路——第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—下篇

简介:

 在上一篇文章中,我介绍了企业库Cryptographer模块的一些重要类,同时介绍了企业库Cryptographer模块为我们提供的扩展接口,今天我就要根据这些接口来进行扩展开发,实现2个加密解密方法(离散加密和对称性加密),分别实现自接口IHashProvider和接口ISymmetricCryptoProvider。

 

首先来看下离散加密——CustomHashCryptography,具体代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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 = 0; 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,这个参数是从配置文件中获取指定的配置属性,见下图:

pic37

注意:这个NameValueCollection类型,需要引用命名空间:using System.Collections.Specialized;

如果没有这个构造函数,将会引发异常:

Type does not provide a constructor taking a single parameter type of NameValueCollection

3、方法CompareHash、CreateHash,接收和返回的类型都是字节数组。

 

接下来看下对称加密CustomSymmetricCryptography ,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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 > 8)
             {
                 encryptKey = encryptKey.Substring(0, 7);
             }
             encryptKey = encryptKey.PadRight(8, ' ' );
             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, 0, inputByteArray.Length);
             cStream.FlushFinalBlock();
             return  mStream.ToArray();
         }
 
         /// <summary>
         /// 解密
         /// </summary>
         /// <param name="plaintext">加密数据</param>
         /// <returns>解密后数据</returns>
         public  byte [] Encrypt( byte [] plaintext)
         {
             if  (encryptKey.Length > 8)
             {
                 encryptKey = encryptKey.Substring(0, 7);
             }
             encryptKey = encryptKey.PadRight(8, ' ' );
             byte [] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
             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, 0, inputByteArray.Length);
             cStream.FlushFinalBlock();
             return  mStream.ToArray();
         }
     }
}

这个对称性加密的注意点基本和离散加密一样,但是这边的对称加密我引入了一个加密key,这个key是从配置文件中获取的。

 

第三点:在项目中应用自定义接口

在上面已经扩展好了2个加密方式,现在就要在实际的项目中运用这2个加密方式,首先打开企业库的配置工具,添加Cryptographer模块,然后在Hash Providers和ISymmetric Cryptograhpy Providers下分别添加刚才定义好的2个加密方式。

注意:添加的自定义加密方式必须放在项目的根目录下,如果放在项目下的文件夹下,如:Helper\Extension下,从企业库的配置文件中将无法找到自定义的加密方式,见下图:

pic38

在添加完配置后就可以在web.config看到以下配置信息:

1
2
3
4
5
6
7
8
9
10
< 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类中添加了几个加密解密方法的封装,用于表示层调用(主要是根据配置实例名和待加密数据获取加密数据),代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <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方法加密录入的密码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <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 学习之路系列文章索引:

第一步、基本入门

第二步、使用VS2010+Data Access模块建立多数据库项目

第三步、为项目加上异常处理(采用自定义扩展方式记录到数据库中) 

第四步、使用缓存提高网站的性能(EntLib Caching)

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——上篇

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——中篇 

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——下篇

第六步、使用Validation模块进行服务器端数据验证

第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—上篇

第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—下篇

第八步、使用Configuration Setting模块等多种方式分类管理企业库配置信息

第九步、使用PolicyInjection模块进行AOP—PART1——基本使用介绍

第九步、使用PolicyInjection模块进行AOP—PART2——自定义Matching Rule

第九步、使用PolicyInjection模块进行AOP—PART3——内置Call Handler介绍

第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

第十步、使用Unity解耦你的系统—PART1——为什么要使用Unity?

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(2)

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)

第十步、使用Unity解耦你的系统—PART3——依赖注入

第十步、使用Unity解耦你的系统—PART4——Unity&PIAB

扩展学习:

扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]

 


本文转自kyo-yo博客园博客,原文链接:http://www.cnblogs.com/kyo-yo/archive/2010/08/11/Learning-EntLib-Seventh-Introduce-Cryptographer-and-Expand-Part2.html,如需转载请自行联系原作者


目录
相关文章
|
2月前
|
供应链 安全 物联网
【接口加密】接口加密的未来发展与应用场景
【接口加密】接口加密的未来发展与应用场景
|
2月前
|
存储 安全 算法
【接口加密】Java中的接口加密实践
【接口加密】Java中的接口加密实践
|
2月前
|
安全 数据安全/隐私保护
【接口加密】理解接口加密的基础概念
【接口加密】理解接口加密的基础概念
|
3月前
|
数据安全/隐私保护 Android开发
2023安卓逆向 -- 某合伙apk登录加密分析
2023安卓逆向 -- 某合伙apk登录加密分析
26 0
|
1月前
|
存储 算法 安全
Python的hashlib模块:7种加密算法深入剖析
Python的hashlib模块:7种加密算法深入剖析
153 0
|
1月前
|
算法 Java 开发工具
使用阿里云KMS产品针对 Springboot 接口参数加密解密功能
针对Springboot里面使用开源工具使用加解密,替换成阿里云KMS产品进行加解密;
146 1
|
2月前
|
存储 前端开发 算法
加密算法在网络通信中的应用及优势分析
本文将探讨加密算法在网络通信中的重要性,以及不同加密算法的应用和优势。通过对前端、后端、Java、Python、C、PHP、Go等多种技术的分析,我们将了解在日益增长的网络威胁下,加密算法对于确保数据安全和隐私保护的必要性。
|
2月前
|
JSON 算法 Java
SpringBoot 实现接口参数加密解密功能
SpringBoot 实现接口参数加密解密功能
154 0
|
2月前
|
数据安全/隐私保护 Python Windows
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)
Python办公自动化【Word转换PDF、PDF读取内容、PDF合并文件、PDF拆分文件、PDF加密文件、PPT基本操作-增加幻灯片、增加内容】(六)-全面详解(学习总结---从入门到深化)
47 0
|
3月前
|
算法 安全 数据安全/隐私保护
C/C++学习 -- 分组加密算法(DES算法)
C/C++学习 -- 分组加密算法(DES算法)
34 0