在C#中实现md5.docx
- 文档编号:24182241
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:21
- 大小:29.53KB
在C#中实现md5.docx
《在C#中实现md5.docx》由会员分享,可在线阅读,更多相关《在C#中实现md5.docx(21页珍藏版)》请在冰豆网上搜索。
在C#中实现md5
在C#中实现MD5加密
一:
关于MD5加密
MD5的全称是Message-DigestAlgorithm5(中文名为消息摘要算法第五版),它用以提供消息的完整性保护。
MD5用的是哈希函数,是计算机网络中应用较多的不可逆加密算法。
在非绝密应用领域甚至绝密领域内,MD5都算得上是一种非常优秀的中间技术。
MD5在90年代初由MIT的计算机科学实验室和RSADataSecurityInc发明,经MD2、MD3和MD4发展而来。
它的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数),MD5最广泛被用于各种软件的密码认证和钥匙识别上。
通俗的讲就是人们讲的序列号。
Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的“字节串”变换成一定长的大整数,这种变换只与字节的值有关,与字符集或编码方式无关。
MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。
可以看出MD5加密是无法进行解密的(也不是绝对的),例如一个string,利用MD5算法进行加密以后你是无法将他还原为原来的string。
MD5不能被解密也不是没用的,因为如果数据没有采用任何加密算法进行加密的话,数据的存储方式是以明文形式存放的,意味着数据有很大能被泄露,但是如果数据经过加密,所看到的也只是一堆毫无排列顺序可言的数字或字符。
MD5加密还有一个特点,就是同一个string在同样的编码方式下加密的结果是一样的,所以可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的“数字指纹”,如果任何人对文件做了任何改动,其MD5值也就是对应的“数字指纹”都会发生变化。
对MD5算法简要的叙述可以为:
MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。
因此,信息的位长(BitsLength)将被扩展至N*512+448,即N*64+56个字节(Bytes),N为一个正整数。
填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。
然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。
经过这两步的处理,现在的信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。
这样做的原因是为满足后面处理中对信息长度的要求。
二:
C#下的MD5加密实现
MD5中有四个32位被称作链接变量(ChainingVariable)的整数参数,他们分别为:
A=0x01234567,B=0x89abcdef,C=0xfedcba98,D=0x76543210。
当设置好这四个链接变量后,就开始进入算法的四轮循环运算。
循环的次数是信息中512位信息分组的数目。
将上面四个链接变量复制到另外四个变量中:
A到a,B到b,C到c,D到d。
主循环有四轮(MD4只有三轮),每轮循环都很相似。
第一轮进行16次操作。
每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。
再将所得结果向右环移一个不定的数,并加上a、b、c或d中之一。
最后用该结果取代a、b、c或d中之一。
以下的例子:
(用的四轮循环)
usingSystem;
usingSystem.Text;
namespaceEncrypter
{
publicclassMD5
{
constintBITS_TO_A_BYTE=8;
constintBYTES_TO_A_WORD=4;
constintBITS_TO_A_WORD=32;
privatestaticlong[]m_lOnBits=newlong[30+1];
privatestaticlong[]m_l2Power=newlong[30+1];
privatestaticlongLShift(longlValue,longiShiftBits)
{
longLShift=0;
if(iShiftBits==0)
{
LShift=lValue;
returnLShift;
}
else
{
if(iShiftBits==31)
{
if(Convert.ToBoolean(lValue&1))
{
LShift=0x80000000;
}
else
{
LShift=0;
}
returnLShift;
}
else
{
if(iShiftBits<0||iShiftBits>31)
{
}
}
}
if(Convert.ToBoolean((lValue&m_l2Power[31-iShiftBits])))
{
LShift=((lValue&m_lOnBits[31-(iShiftBits+1)])*m_l2Power[iShiftBits])|0x80000000;
}
else
{
LShift=((lValue&m_lOnBits[31-iShiftBits])*m_l2Power[iShiftBits]);
}
returnLShift;
}
privatestaticlongRShift(longlValue,longiShiftBits)
{
longRShift=0;
if(iShiftBits==0)
{
RShift=lValue;
returnRShift;
}
else
{
if(iShiftBits==31)
{
if(Convert.ToBoolean(lValue&0x80000000))
{
RShift=1;
}
else
{
RShift=0;
}
returnRShift;
}
else
{
if(iShiftBits<0||iShiftBits>31)
{
//Err.Raise6;
}
}
}
RShift=(lValue&0x7FFFFFFE)/m_l2Power[iShiftBits];
if(Convert.ToBoolean((lValue&0x80000000)))
{
RShift=(RShift|(0x40000000/m_l2Power[iShiftBits-1]));
}
returnRShift;
}
privatestaticlongRotateLeft(longlValue,longiShiftBits)
{
longRotateLeft=0;
RotateLeft=LShift(lValue,iShiftBits)|RShift(lValue,(32-iShiftBits));
returnRotateLeft;
}
privatestaticlongAddUnsigned(longlX,longlY)
{
longAddUnsigned=0;
longlX4=0;
longlY4=0;
longlX8=0;
longlY8=0;
longlResult=0;
lX8=lX&0x80000000;
lY8=lY&0x80000000;
lX4=lX&0x40000000;
lY4=lY&0x40000000;
lResult=(lX&0x3FFFFFFF)+(lY&0x3FFFFFFF);
if(Convert.ToBoolean(lX4&lY4))
{
lResult=lResult^0x80000000^lX8^lY8;
}
elseif(Convert.ToBoolean(lX4|lY4))
{
if(Convert.ToBoolean(lResult&0x40000000))
{
lResult=lResult^0xC0000000^lX8^lY8;
}
else
{
lResult=lResult^0x40000000^lX8^lY8;
}
}
else
{
lResult=lResult^lX8^lY8;
}
AddUnsigned=lResult;
returnAddUnsigned;
}
privatestaticlongmd5_F(longx,longy,longz)
{
longmd5_F=0;
md5_F=(x&y)|((~x)&z);
returnmd5_F;
}
privatestaticlongmd5_G(longx,longy,longz)
{
longmd5_G=0;
md5_G=(x&z)|(y&(~z));
returnmd5_G;
}
privatestaticlongmd5_H(longx,longy,longz)
{
longmd5_H=0;
md5_H=(x^y^z);
returnmd5_H;
}
privatestaticlongmd5_I(longx,longy,longz)
{
longmd5_I=0;
md5_I=(y^(x|(~z)));
returnmd5_I;
}
privatestaticvoidmd5_FF(reflonga,longb,longc,longd,longx,longs,longac)
{
a=AddUnsigned(a,AddUnsigned(AddUnsigned(md5_F(b,c,d),x),ac));
a=RotateLeft(a,s);
a=AddUnsigned(a,b);
}
privatestaticvoidmd5_GG(reflonga,longb,longc,longd,longx,longs,longac)
{
a=AddUnsigned(a,AddUnsigned(AddUnsigned(md5_G(b,c,d),x),ac));
a=RotateLeft(a,s);
a=AddUnsigned(a,b);
}
privatestaticvoidmd5_HH(reflonga,longb,longc,longd,longx,longs,longac)
{
a=AddUnsigned(a,AddUnsigned(AddUnsigned(md5_H(b,c,d),x),ac));
a=RotateLeft(a,s);
a=AddUnsigned(a,b);
}
privatestaticvoidmd5_II(reflonga,longb,longc,longd,longx,longs,longac)
{
a=AddUnsigned(a,AddUnsigned(AddUnsigned(md5_I(b,c,d),x),ac));
a=RotateLeft(a,s);
a=AddUnsigned(a,b);
}
privatestaticlong[]ConvertToWordArray(stringsMessage)
{
long[]ConvertToWordArray=null;
intlMessageLength=0;
intlNumberOfWords=0;
long[]lWordArray=null;
intlBytePosition=0;
intlByteCount=0;
intlWordCount=0;
constintMODULUS_BITS=512;
constintCONGRUENT_BITS=448;
lMessageLength=sMessage.Length;
lNumberOfWords=(((lMessageLength+((MODULUS_BITS-CONGRUENT_BITS)/BITS_TO_A_BYTE))/(MODULUS_BITS/BITS_TO_A_BYTE))+1)*(MODULUS_BITS/BITS_TO_A_WORD);
lWordArray=newlong[lNumberOfWords];
lBytePosition=0;
lByteCount=0;
while(lByteCount { lWordCount=lByteCount/BYTES_TO_A_WORD; lBytePosition=(lByteCount%BYTES_TO_A_WORD)*BITS_TO_A_BYTE; lWordArray[lWordCount]=lWordArray[lWordCount]|LShift(Convert.ToByte(sMessage.Substring(lByteCount,1).ToCharArray()[0]),lBytePosition); lByteCount=lByteCount+1; } lWordCount=lByteCount/BYTES_TO_A_WORD; lBytePosition=(lByteCount%BYTES_TO_A_WORD)*BITS_TO_A_BYTE; lWordArray[lWordCount]=lWordArray[lWordCount]|LShift(0x80,lBytePosition); lWordArray[lNumberOfWords-2]=LShift(lMessageLength,3); lWordArray[lNumberOfWords-1]=RShift(lMessageLength,29); ConvertToWordArray=lWordArray; returnConvertToWordArray; } privatestaticstringWordToHex(longlValue) { stringWordToHex=""; longlByte=0; intlCount=0; for(lCount=0;lCount<=3;lCount++) { lByte=RShift(lValue,lCount*BITS_TO_A_BYTE)&m_lOnBits[BITS_TO_A_BYTE-1]; WordToHex=WordToHex+(("0"+ToHex(lByte)).Substring(("0"+ToHex(lByte)).Length-2)); } returnWordToHex; } privatestaticstringToHex(longdec) { stringstrhex=""; while(dec>0) { strhex=tohex(dec%16)+strhex; dec=dec/16; } returnstrhex; } privatestaticstringtohex(longhex) { stringstrhex=""; switch(hex) { case10: strhex="a";break; case11: strhex="b";break; case12: strhex="c";break; case13: strhex="d";break; case14: strhex="e";break; case15: strhex="f";break; default: strhex=hex.ToString();break; } returnstrhex; } publicstaticstringEncrypt(stringsMessage,intstype) { stringMD5=""; for(inti=0;i<=30;i++) { m_lOnBits=Convert.ToInt64(Math.Pow(2,i+1)-1); m_l2Power=Convert.ToInt64(Math.Pow(2,i)); } long[]x=null; intk=0; longAA=0; longBB=0; longCC=0; longDD=0; longa=0; longb=0; longc=0; longd=0; constintS11=7; constintS12=12; constintS13=17; constintS14=22; constintS21=5; constintS22=9; constintS23=14; constintS24=20; constintS31=4; constintS32=11; constintS33=16; constintS34=23; constintS41=6; constintS42=10; constintS43=15; constintS44=21; x=ConvertToWordArray(sMessage); a=0x67452301; b=0xEFCDAB89; c=0x98BADCFE; d=0x10325476; for(k=0;k { AA=a; BB=b; CC=c; DD=d; //第一轮循环左移开始 md5_FF(refa,b,c,d,x[k+0],S11,0xD76AA478); md5_FF(refd,a,b,c,x[k+1],S12,0xE8C7B756); md5_FF(refc,d,a,b,x[k+2],S13,0x242070DB); md5_FF(refb,c,d,a,x[k+3],S14,0xC1BDCEEE); md5_FF(refa,b,c,d,x[k+4],S11,0xF57C0FAF); md5_FF(refd,a,b,c,x[k+5],S12,0x4787C62A); md5_FF(refc,d,a,b,x[k+6],S13,0xA8304613); md5_FF(refb,c,d,a,x[k+7],S14,0xFD469501); md5_FF(refa,b,c,d,x[k+8],S11,0x698098D8); md5_FF(refd,a,b,c,x[k+9],S12,0x8B44F7AF); md5_FF(refc,d,a,b,x[k+10],S13,0xFFFF5BB1); md5_FF(refb,c,d,a,x[k+11],S14,0x895CD7BE); md5_FF(refa,b,c,d,x[k+12],S11,0x6B901122); md5_FF(refd,a,b,c,x[k+13],S12,0xFD987193); md5_FF(refc,d,a,b,x[k+14],S13,0xA679438E); md5_FF(refb,c,d,a,x[k+15],S14,0x49B40821); //第二轮左移开始 md5_GG(refa,b,c,d,x[k+1],S21,0xF61E2562); md5_GG(refd,a,b,c,x[k+6],S22,0xC040B340); md5_GG(refc,d,a,b,x[k+11],S23,0x265E5A51); md5_GG(refb,c,d,a,x[k+0],S24,0xE9B6C7AA); md5_GG(refa,b,c,d,x[k+5],S21,0xD62F105D); md5_GG(refd,a,b,c,x[k+10],S22,0x2441453); md5_GG(refc,d,a,b,x[k+15],S23,0xD8A1E681); md5_GG(refb,c,d,a,x[k+4],S24,0xE7D3FBC8); md5_GG(refa,b,c,d,x[k+9],S21,0x21E1CDE6); md5_GG(refd,a,b,c,x[k+14],S22,0xC33707D6); md5_GG(refc,d,a,b,x[k+3],S23,0xF4D50D87); md5_GG(refb,c,d,a,x[k+8
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 实现 md5
![提示](https://static.bdocx.com/images/bang_tan.gif)