ADONET数据加密之一

一、常用数据加密

1.MD5,全称Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护,MD5通常是使用16进制数来表示的,所以一共是16种字符(0-9,A-F)。例如:1D62713DF71A7FAA58D678E78B9E3995。

特性:MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。我觉得是没有人们还有真正发现破解之道,至于MD5值怎么计算的以后细细讨论。

从网上找了点MD5算法,仅从参考

 

首先填充消息使其长度恰好为一个比512位的倍数仅小64位的数。填充方法是附一个1在消息后面,后接所要求的多个0,然后在其后附上64位的消息长度(填充前)。这两步的作用是使消息长度恰好是512位的整数倍(算法的其余部分要求如此),同时确保不同的消息在填充后不相同。 
四个32位变量初始化为: 
A=0x01234567 
B=0x89abcdef 
C=0xfedcba98 
D=0x76543210 
它们称为链接变量(chaining variable) 
接着进行算法的主循环,循环的次数是消息中512位消息分组的数目。 
将上面四个变量复制到别外的变量中:A到a,B到b,C到c,D到d。 
主循环有四轮(MD4只有三轮),每轮很相拟。第一轮进行16次操作。每次操作对a,b,c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向右环移一个不定的数,并加上a,b,c或d中之一。最后用该结果取代a,b,c或d中之一。 
以一下是每次操作中用到的四个非线性函数(每轮一个)。 
F(X,Y,Z)=(X&Y)|((~X)&Z) 
G(X,Y,Z)=(X&Z)|(Y&(~Z)) 
H(X,Y,Z)=X^Y^Z 
I(X,Y,Z)=Y^(X|(~Z)) 
(&是与,|是或,~是非,^是异或) 
这些函数是这样设计的:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。 
函数F是按逐位方式操作:如果X,那么Y,否则Z。函数H是逐位奇偶操作符。 
设Mj表示消息的第j个子分组(从0到15),<<< s表示循环左移s位,则四种操作为: 
FF(a,b,c,d,Mj,s,ti)表示a=b+((a+(F(b,c,d)+Mj+ti)<<< s) 
GG(a,b,c,d,Mj,s,ti)表示a=b+((a+(G(b,c,d)+Mj+ti)<<< s) 
HH(a,b,c,d,Mj,s,ti)表示a=b+((a+(H(b,c,d)+Mj+ti)<<< s) 
II(a,b,c,d,Mj,s,ti)表示a=b+((a+(I(b,c,d)+Mj+ti)<<< s) 
这四轮(64步)是: 
第一轮 
FF(a,b,c,d,M0,7,0xd76aa478) 
FF(d,a,b,c,M1,12,0xe8c7b756) 
FF(c,d,a,b,M2,17,0x242070db) 
FF(b,c,d,a,M3,22,0xc1bdceee) 
FF(a,b,c,d,M4,7,0xf57c0faf) 
FF(d,a,b,c,M5,12,0x4787c62a) 
FF(c,d,a,b,M6,17,0xa8304613) 
FF(b,c,d,a,M7,22,0xfd469501) 
FF(a,b,c,d,M8,7,0x698098d8) 
FF(d,a,b,c,M9,12,0x8b44f7af) 
FF(c,d,a,b,M10,17,0xffff5bb1) 
FF(b,c,d,a,M11,22,0x895cd7be) 
FF(a,b,c,d,M12,7,0x6b901122) 
FF(d,a,b,c,M13,12,0xfd987193) 
FF(c,d,a,b,M14,17,0xa679438e) 
FF(b,c,d,a,M15,22,0x49b40821) 
第二轮 
GG(a,b,c,d,M1,5,0xf61e2562) 
GG(d,a,b,c,M6,9,0xc040b340) 
GG(c,d,a,b,M11,14,0x265e5a51) 
GG(b,c,d,a,M0,20,0xe9b6c7aa) 
GG(a,b,c,d,M5,5,0xd62f105d) 
GG(d,a,b,c,M10,9,0x02441453) 
GG(c,d,a,b,M15,14,0xd8a1e681) 
GG(b,c,d,a,M4,20,0xe7d3fbc8) 
GG(a,b,c,d,M9,5,0x21e1cde6) 
GG(d,a,b,c,M14,9,0xc33707d6) 
GG(c,d,a,b,M3,14,0xf4d50d87) 
GG(b,c,d,a,M8,20,0x455a14ed) 
GG(a,b,c,d,M13,5,0xa9e3e905) 
GG(d,a,b,c,M2,9,0xfcefa3f8) 
GG(c,d,a,b,M7,14,0x676f02d9) 
GG(b,c,d,a,M12,20,0x8d2a4c8a) 
第三轮 
HH(a,b,c,d,M5,4,0xfffa3942) 
HH(d,a,b,c,M8,11,0x8771f681) 
HH(c,d,a,b,M11,16,0x6d9d6122) 
HH(b,c,d,a,M14,23,0xfde5380c) 
HH(a,b,c,d,M1,4,0xa4beea44) 
HH(d,a,b,c,M4,11,0x4bdecfa9) 
HH(c,d,a,b,M7,16,0xf6bb4b60) 
HH(b,c,d,a,M10,23,0xbebfbc70) 
HH(a,b,c,d,M13,4,0x289b7ec6) 
HH(d,a,b,c,M0,11,0xeaa127fa) 
HH(c,d,a,b,M3,16,0xd4ef3085) 
HH(b,c,d,a,M6,23,0x04881d05) 
HH(a,b,c,d,M9,4,0xd9d4d039) 
HH(d,a,b,c,M12,11,0xe6db99e5) 
HH(c,d,a,b,M15,16,0x1fa27cf8) 
HH(b,c,d,a,M2,23,0xc4ac5665) 
第四轮 
II(a,b,c,d,M0,6,0xf4292244) 
II(d,a,b,c,M7,10,0x432aff97) 
II(c,d,a,b,M14,15,0xab9423a7) 
II(b,c,d,a,M5,21,0xfc93a039) 
II(a,b,c,d,M12,6,0x655b59c3) 
II(d,a,b,c,M3,10,0x8f0ccc92) 
II(c,d,a,b,M10,15,0xffeff47d) 
II(b,c,d,a,M1,21,0x85845dd1) 
II(a,b,c,d,M8,6,0x6fa87e4f) 
II(d,a,b,c,M15,10,0xfe2ce6e0) 
II(c,d,a,b,M6,15,0xa3014314) 
II(b,c,d,a,M13,21,0x4e0811a1) 
II(a,b,c,d,M4,6,0xf7537e82) 
II(d,a,b,c,M11,10,0xbd3af235) 
II(c,d,a,b,M2,15,0x2ad7d2bb) 
II(b,c,d,a,M9,21,0xeb86d391) 
常数ti可以如下选择: 
在第i步中,ti是4294967296*abs(sin(i))的整数部分,i的单位是弧度。 
(2的32次方) 
所有这些完成之后,将A,B,C,D分别加上a,b,c,d。然后用下一分组数据继续运行算法,最后的输出是A,B,C和D的级联。 
MD5的安全性 

MD5相对MD4所作的改进: 
1.增加了第四轮. 
2.每一步均有唯一的加法常数. 
3.为减弱第二轮中函数G的对称性从(X&Y)|(X&Z)|(Y&Z)变为(X&Z)|(Y&(~Z)) 
4.第一步加上了上一步的结果,这将引起更快的雪崩效应. 
5.改变了第二轮和第三轮中访问消息子分组的次序,使其更不相似. 
6.近似优化了每一轮中的循环左移位移量以实现更快的雪崩效应.各轮的位移量互不相同
应用:数据加密

ADONET数据加密的一般过程

1.数据加密

引入数据加密的命名空间,和方法如下

 

(1)System.Security.Cryptography命名空间
System.Security.Cryptography 命名空间提供加密服务(包括安全的数据编码和解码)以及许多其他操作,例如散列法、随机数字生成和消息身份验证。
(2)MD5CryptoServiceProvider类
此类使用加密服务提供程序(CSP)提供的实现,计算输入数据的MD5哈希值。
语法格式为:
public sealed class MD5CryptoServiceProvider : MD5
 注意:MD5CryptoServiceProvider类的哈希大小为128位。
(3)ComputeHash( )方法
此方法计算指定字节数组的哈希值。
语法格式为:
public byte[] ComputeHash (byte[] buffer)
参数说明如下。
l     buffer:要计算其哈希代码的字节数组。
l     返回值:计算所得的哈希代码。
(4)System.Text命名空间
表示 ASCII、Unicode、UTF-7和UTF-8字符编码的类;是用于将字符块转换为字节块和将字节块转换为字符块的抽象基类。
(5)ASCIIEncoding类
此类表示Unicode字符的ASCII字符编码。
语法格式为:
    public class ASCIIEncoding : Encoding
(6)ASCII属性
此属性获取 ASCII(7位)字符集的编码。
语法格式为:
public static Encoding ASCII { get; }
l     属性值:ASCII(7 位)字符集的Encoding。
(7)GetBytes( )方法
此方法将指定的String中的所有字符编码为一个字节序列。
语法格式为:
public virtual byte[] GetBytes (string s)
参数说明如下。
l     s:包含要编码的字符的String。
(8)GetString( )方法
此方法将指定字节数组中的所有字节解码为一个字符串。
语法格式为:
public virtual string GetString (byte[] bytes)
参数说明如下。
l     bytes:包含要解码的字节序列的字节数组。
l     返回值:包含指定字节序列解码结果的String

 

 

ADO.NET代码实现

/// <summary>
    /// MD5 
    /// </summary>
    /// <param name="text">加密字符串</param>
    /// <returns></returns>
    public static string  MD5Encrpty(string text) {
    //1.将字符串转换成字节数组,使用系统默认字符集。
        byte[] startText = System.Text.Encoding.Default.GetBytes(text);
        
    //2.生成一个MD5加密对象,用于加密
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
   //3.计算字节数组的哈希值
        byte[] resultText = md5.ComputeHash(startText);
    
        //BitConverter,采用系统默认字符集,所以编码时,必须采用系统默认字符集,否则字符中有汉字的时,结果偏差
        return BitConverter.ToString(resultText).Replace("-","");
    }

2.DES 最著名的保密密钥或对称密钥加密算法DES(Data Encryption Standard)是由IBM公司在70年代发展起来的。

ADO.NET实现代码

/// <summary>
    /// DES加密
    /// </summary>
    /// <param name="text">加密字符串</param>
    /// <param name="desKey">密钥,密钥字符长度必须是八位</param>
    /// <returns></returns>
    public static string DESEncrypt(string text,string enKey) {
        //1.加密字符串转换成字节数组
        byte[] startText = Encoding.Default.GetBytes(text);
        //密钥字符长度必须是八位。
        byte[] startKey = Encoding.Default.GetBytes(enKey);
        //初始化加密字符串,可以不写。
        byte[] m_btIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        //2.创建加密对象
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        //3.创建内存流
        MemoryStream m_stream = new MemoryStream();
        //4.创建加密构造器
       ICryptoTransform transfrom= des.CreateEncryptor(startKey,m_btIV);
        //5.创建加密流,传入内存流,加密构造器,方式
        CryptoStream mc_stream = new CryptoStream(m_stream,transfrom,CryptoStreamMode.Write);
        //6.加密字符串写入流中
        mc_stream.Write(startText,0,startText.Length);
        //7.输出所有加密流
        mc_stream.FlushFinalBlock();
        //8.释放资源
        m_stream.Close(); m_stream.Dispose();
        mc_stream.Close(); mc_stream.Dispose();
        //注意,返回字符串方式,接受字符串方式
        return Convert.ToBase64String(m_stream.ToArray());
    }
    /// <summary>
    /// DES解密
    /// </summary>
    /// <param name="text">要解密字符串,格式Base64String</param>
    /// <param name="deKey"></param>
    /// <returns></returns>
    public static string DESDecrypt(string text,string deKey) {
        //1.接受解密字符串
        byte[] startText = Convert.FromBase64String(text);
       int r= startText.Length;
        //转换密钥
        byte[] startKey = Encoding.Default.GetBytes(deKey);
        //初始化字符串
        byte[] m_btIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        //2.创建加密对象
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        //3.创建内存流
        MemoryStream m_stream = new MemoryStream();
        //4.创建解密构造器
        ICryptoTransform transfrom = des.CreateDecryptor(startKey, m_btIV);
        //5.创建加密流,传入内存流,解密构造器,方式
        CryptoStream mc_stream = new CryptoStream(m_stream, transfrom, CryptoStreamMode.Write);
        //6.解密字符串写入流中
        mc_stream.Write(startText, 0, startText.Length);
        //7.输出所有解密流
        mc_stream.FlushFinalBlock();
        //8.释放资源
        m_stream.Close(); m_stream.Dispose();


        mc_stream.Close(); mc_stream.Dispose();


        return Encoding.Default.GetString(m_stream.ToArray());
    }


posted @ 2012-01-07 21:53  刀锋_Master  阅读(329)  评论(0编辑  收藏  举报