#ifndef MD5_H
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:國際域名空間、網(wǎng)站空間、營銷軟件、網(wǎng)站建設、陵水黎族網(wǎng)站維護、網(wǎng)站推廣。
#define MD5_H
typedef struct
{
unsigned int count[2];
unsigned int state[4];
unsigned char buffer[64];
}MD5_CTX;
#define F(x,y,z) ((x y) | (~x z))
#define G(x,y,z) ((x z) | (y ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
#define ROTATE_LEFT(x,n) ((x n) | (x (32-n)))
#define FF(a,b,c,d,x,s,ac) \
{ \
a += F(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define GG(a,b,c,d,x,s,ac) \
{ \
a += G(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define HH(a,b,c,d,x,s,ac) \
{ \
a += H(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define II(a,b,c,d,x,s,ac) \
{ \
a += I(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
void MD5Transform(unsigned int state[4],unsigned char block[64]);
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
#endif
源文件md5.c
#include memory.h
#include "md5.h"
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void MD5Init(MD5_CTX *context)
{
context-count[0] = 0;
context-count[1] = 0;
context-state[0] = 0x67452301;
context-state[1] = 0xEFCDAB89;
context-state[2] = 0x98BADCFE;
context-state[3] = 0x10325476;
}
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
{
unsigned int i = 0,index = 0,partlen = 0;
index = (context-count[0] 3) 0x3F;
partlen = 64 - index;
context-count[0] += inputlen 3;
if(context-count[0] (inputlen 3))
context-count[1]++;
context-count[1] += inputlen 29;
if(inputlen = partlen)
{
memcpy(context-buffer[index],input,partlen);
MD5Transform(context-state,context-buffer);
for(i = partlen;i+64 = inputlen;i+=64)
MD5Transform(context-state,input[i]);
index = 0;
}
else
{
i = 0;
}
memcpy(context-buffer[index],input[i],inputlen-i);
}
void MD5Final(MD5_CTX *context,unsigned char digest[16])
{
unsigned int index = 0,padlen = 0;
unsigned char bits[8];
index = (context-count[0] 3) 0x3F;
padlen = (index 56)?(56-index):(120-index);
MD5Encode(bits,context-count,8);
MD5Update(context,PADDING,padlen);
MD5Update(context,bits,8);
MD5Encode(digest,context-state,16);
}
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j len)
{
output[j] = input[i] 0xFF;
output[j+1] = (input[i] 8) 0xFF;
output[j+2] = (input[i] 16) 0xFF;
output[j+3] = (input[i] 24) 0xFF;
i++;
j+=4;
}
}
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j len)
{
output[i] = (input[j]) |
(input[j+1] 8) |
(input[j+2] 16) |
(input[j+3] 24);
i++;
j+=4;
}
}
void MD5Transform(unsigned int state[4],unsigned char block[64])
{
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
unsigned int x[64];
MD5Decode(x,block,64);
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
相關(guān)庫函數(shù)如下:
#include openssl/md5.h
unsigned char *MD5(const unsigned char *d, unsigned long n,unsigned char *md);
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data,unsigned long len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
介紹MD5加密算法基本情況MD5的全稱是Message-Digest Algorithm 5,在90年代初由MIT的計算機科學實驗室和RSA Data Security Inc發(fā)明,經(jīng)MD2、MD3和MD4發(fā)展而來。
Message-Digest泛指字節(jié)串(Message)的Hash變換,就是把一個任意長度的字節(jié)串變換成一定長的大整數(shù)。請注意我使用了"字節(jié)串"而不是"字符串"這個詞,是因為這種變換只與字節(jié)的值有關(guān),與字符集或編碼方式無關(guān)。
MD5將任意長度的"字節(jié)串"變換成一個128bit的大整數(shù),并且它是一個不可逆的字符串變換算法,換句話說就是,即使你看到源程序和算法描述,也無法將一個MD5的值變換回原始的字符串,從數(shù)學原理上說,是因為原始的字符串有無窮多個,這有點象不存在反函數(shù)的數(shù)學函數(shù)。
MD5的典型應用是對一段Message(字節(jié)串)產(chǎn)生fingerprint(指紋),以防止被"篡改"。舉個例子,你將一段話寫在一個叫readme.txt文件中,并對這個readme.txt產(chǎn)生一個MD5的值并記錄在案,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內(nèi)容,你對這個文件重新計算MD5時就會發(fā)現(xiàn)。如果再有一個第三方的認證機構(gòu),用MD5還可以防止文件作者的"抵賴",這就是所謂的數(shù)字簽名應用。
MD5還廣泛用于加密和解密技術(shù)上,在很多操作系統(tǒng)中,用戶的密碼是以MD5值(或類似的其它算法)的方式保存的,用戶Login的時候,系統(tǒng)是把用戶輸入的密碼計算成MD5值,然后再去和系統(tǒng)中保存的MD5值進行比較,而系統(tǒng)并不"知道"用戶的密碼是什么。
一些黑客破獲這種密碼的方法是一種被稱為"跑字典"的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字符串表,另一種是用排列組合方法生成的,先用MD5程序計算出這些字典項的MD5值,然后再用目標的MD5值在這個字典中檢索。
即使假設密碼的最大長度為8,同時密碼只能是字母和數(shù)字,共26+26+10=62個字符,排列組合出的字典的項數(shù)則是P(62,1)+P(62,2)....+P(62,8),那也已經(jīng)是一個很天文的數(shù)字了,存儲這個字典就需要TB級的磁盤組,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼MD5值的情況下才可以。
在很多電子商務和社區(qū)應用中,管理用戶的Account是一種最常用的基本功能,盡管很多Application Server提供了這些基本組件,但很多應用開發(fā)者為了管理的更大的靈活性還是喜歡采用關(guān)系數(shù)據(jù)庫來管理用戶,懶惰的做法是用戶的密碼往往使用明文或簡單的變換后直接保存在數(shù)據(jù)庫中,因此這些用戶的密碼對軟件開發(fā)者或系統(tǒng)管理員來說可以說毫無保密可言,本文的目的是介紹MD5的Java Bean的實現(xiàn),同時給出用MD5來處理用戶的Account密碼的例子,這種方法使得管理員和程序設計者都無法看到用戶的密碼,盡管他們可以初始化它們。但重要的一點是對于用戶密碼設置習慣的保護