⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md5digest.cpp

📁 跨操作系统的微型中间件
💻 CPP
字号:
#ifdef WIN32/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc.  All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License.  Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.  Please * see the License for the specific language governing rights and * limitations under the License. * * * @APPLE_LICENSE_HEADER_END@ * *//*	File:		md5digest.cpp	Contains:   Implements the function declared in md5digest.h*/#include "md5.h"#include "md5digest.h"#include "StrPtrLen.h"#include <string.h>//#include "OSMemory.h"static StrPtrLen sColon(":", 1);static StrPtrLen sMD5Sess("md5-sess", 8);static StrPtrLen sQopAuth("auth", 4);static StrPtrLen sQopAuthInt("auth-int", 8);// allocates memory for hashStr->Ptrvoid HashToString(unsigned char aHash[kHashLen], StrPtrLen* hashStr){	UInt16 i;	UInt8 hexDigit;	// Allocating memory	char* str = new char[kHashHexLen+1];	str[kHashHexLen] = 0;			for(i = 0; i < kHashLen; i++) {		hexDigit = (aHash[i] >> 4) & 0xF;		str[i*2] = (hexDigit <= 9) ? (hexDigit + '0') : (hexDigit + 'a' - 10);		hexDigit = aHash[i] & 0xF;		str[i*2 + 1] = (hexDigit <= 9) ? (hexDigit + '0') : (hexDigit + 'a' - 10);	}		hashStr->Ptr = str;	hashStr->Len = kHashHexLen;}// allocates memory for hashA1Hex16Bit->Ptrvoid CalcMD5HA1( StrPtrLen* userName, 			  	 StrPtrLen* realm,			     StrPtrLen* userPassword, 			     StrPtrLen* hashA1Hex16Bit			   ) {	// parameters must be valid pointers 	// It is ok if parameter->Ptr is NULL as long as parameter->Len is 0	Assert(userName);	Assert(realm);	Assert(userPassword);	Assert(hashA1Hex16Bit);	Assert(hashA1Hex16Bit->Ptr == NULL); //This is the result. A Ptr here will be replaced. Value should be NULL.		MD5_CTX context;	unsigned char* aHash = new unsigned char[kHashLen];		// Calculate H(A1) for MD5	// where A1 for algorithm = "md5" or if nothing is specified is	// 				A1 	= userName:realm:userPassword	MD5_Init(&context);	MD5_Update(&context, (unsigned char *)userName->Ptr, userName->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)realm->Ptr, realm->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)userPassword->Ptr, userPassword->Len);	MD5_Final(aHash, &context);	hashA1Hex16Bit->Ptr = (char *)aHash;	hashA1Hex16Bit->Len = kHashLen;}// allocates memory to hA1->Ptrvoid CalcHA1( StrPtrLen* algorithm, 			  StrPtrLen* userName, 			  StrPtrLen* realm,			  StrPtrLen* userPassword, 			  StrPtrLen* nonce, 			  StrPtrLen* cNonce,			  StrPtrLen* hA1			) {	// parameters must be valid pointers 	// It is ok if parameter->Ptr is NULL as long as parameter->Len is 0	Assert(algorithm);	Assert(userName);	Assert(realm);	Assert(userPassword);	Assert(nonce);	Assert(cNonce);	Assert(hA1);	Assert(hA1->Ptr == NULL); //This is the result. A Ptr here will be replaced. Value should be NULL.		MD5_CTX context;	unsigned char aHash[kHashLen];		// Calculate H(A1)	// where A1 for algorithm = "md5" or if nothing is specified is	// 				A1 	= userName:realm:userPassword	// and for algorithm = "md5-sess" is	// 				A1	= H(userName:realm:userPassword):nonce:cnonce	MD5_Init(&context);	MD5_Update(&context, (unsigned char *)userName->Ptr, userName->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)realm->Ptr, realm->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)userPassword->Ptr, userPassword->Len);	MD5_Final(aHash, &context);	if(algorithm->Equal(sMD5Sess)) {		MD5_Init(&context);		MD5_Update(&context, aHash, kHashLen);		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);		MD5_Update(&context, (unsigned char *)nonce->Ptr, nonce->Len);		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);		MD5_Update(&context, (unsigned char *)cNonce->Ptr, cNonce->Len);		MD5_Final(aHash, &context);	}	HashToString(aHash, hA1);}// allocates memory to hA1->Ptrvoid CalcHA1Md5Sess(StrPtrLen* hashA1Hex16Bit, StrPtrLen* nonce, StrPtrLen* cNonce, StrPtrLen* hA1){	// parameters must be valid pointers 	// It is ok if parameter->Ptr is NULL as long as parameter->Len is 0	Assert(hashA1Hex16Bit);	Assert(hashA1Hex16Bit->Len == kHashLen);	Assert(nonce);	Assert(cNonce);	Assert(hA1);	Assert(hA1->Ptr == NULL); //This is the result. A Ptr here will be replaced. Value should be NULL.		MD5_CTX context;	unsigned char aHash[kHashLen];		MD5_Init(&context);	MD5_Update(&context, (unsigned char *)hashA1Hex16Bit->Ptr, kHashLen);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)nonce->Ptr, nonce->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)cNonce->Ptr, cNonce->Len);	MD5_Final(aHash, &context);		// allocates memory to hA1->Ptr	HashToString(aHash, hA1);}// allocates memory for requestDigest->Ptr				void CalcRequestDigest(	StrPtrLen* hA1, 						StrPtrLen* nonce, 						StrPtrLen* nonceCount, 						StrPtrLen* cNonce,						StrPtrLen* qop,						StrPtrLen* method, 						StrPtrLen* digestUri, 						StrPtrLen* hEntity, 						StrPtrLen* requestDigest					  ){	// parameters must be valid pointers 	// It is ok if parameter->Ptr is NULL as long as parameter->Len is 0	Assert(hA1);	Assert(nonce);	Assert(nonceCount);	Assert(cNonce);	Assert(qop);	Assert(method);	Assert(digestUri);	Assert(hEntity);	Assert(requestDigest);	Assert(requestDigest->Ptr == NULL); //This is the result. A Ptr here will be replaced. Value should be NULL.	unsigned char aHash[kHashLen], requestHash[kHashLen];	StrPtrLen hA2;	MD5_CTX context;			// H(data) = MD5(data)	// and KD(secret, data) = H(concat(secret, ":", data))		// Calculate H(A2)	// where A2 for qop="auth" or no qop is 	//				A2	= method:digestUri	// and for qop = "auth-int" is	//				A2 = method:digestUri:H(entity-body)	MD5_Init(&context);	MD5_Update(&context, (unsigned char *)method->Ptr, method->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)digestUri->Ptr, digestUri->Len);	if(qop->Equal(sQopAuthInt)) {		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);		MD5_Update(&context, (unsigned char *)hEntity->Ptr, hEntity->Len);	}	MD5_Final(aHash, &context);		// HashToString allocates memory for hA2...delete it after request-digest is created	HashToString(aHash, &hA2);	// Calculate request-digest	// where request-digest for qop="auth" or qop="auth-int" is	// 			request-digest	= KD( H(A1), nonce:nonceCount:cNonce:qop:H(A2) )	// and if qop directive isn't present is	//			request-digest = KD( H(A1), nonce:H(A2) )	MD5_Init(&context);	MD5_Update(&context, (unsigned char *)hA1->Ptr, hA1->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	MD5_Update(&context, (unsigned char *)nonce->Ptr, nonce->Len);	MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	if(qop->Ptr != NULL) {		MD5_Update(&context, (unsigned char *)nonceCount->Ptr, nonceCount->Len);		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);		MD5_Update(&context, (unsigned char *)cNonce->Ptr, cNonce->Len);		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);		MD5_Update(&context, (unsigned char *)qop->Ptr, qop->Len);		MD5_Update(&context, (unsigned char *)sColon.Ptr, sColon.Len);	}	MD5_Update(&context, (unsigned char *)hA2.Ptr, hA2.Len);	MD5_Final(requestHash, &context);	HashToString(requestHash, requestDigest);		// Deleting memory allocated for hA2	delete [] hA2.Ptr;}/* From local_passwd.c (C) Regents of Univ. of California blah blah */static unsigned char itoa64[] =	/* 0 ... 63 => ascii - 64 */"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";void to64(register char *s, register long v, register int n){    while (--n >= 0) {	*s++ = itoa64[v & 0x3f];	v >>= 6;    }}/* * Define the Magic String prefix that identifies a password as being * hashed using our algorithm. */static const char *dufr_id = "$dufr$";// Doesn't allocate any memory. The size of the result buffer should be nbytesvoid MD5Encode(const char *pw, const char *salt, char *result, int nbytes){  /*   * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,   * plus 4 for the '$' separators, plus the password hash itself.   * Let's leave a goodly amount of leeway.   */    char passwd[120], *p;  const char *sp, *ep;  unsigned char final[kHashLen];  int sl, pl, i;  MD5_CTX ctx, ctx1;  unsigned long l;   /*   * Refine the salt first.  It's possible we were given an already-hashed   * string as the salt argument, so extract the actual salt value from it   * if so.  Otherwise just use the string up to the first '$' as the salt.   */  sp = salt;  //If it starts with the magic string, then skip that.  if (!strncmp(sp, dufr_id, strlen(dufr_id)))   {    sp += strlen(dufr_id);  }  //It stops at the first '$' or 8 chars, whichever comes first  for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++)   {    continue;  }  //Get the length of the true salt  sl = ep - sp;    //'Time to make the doughnuts..'  MD5_Init(&ctx);  //The password first, since that is what is most unknown  MD5_Update(&ctx, (unsigned char *)pw, strlen(pw));  //Then our magic string  MD5_Update(&ctx, (unsigned char *)dufr_id, strlen(dufr_id));  //Then the raw salt  MD5_Update(&ctx, (unsigned char *)sp, sl);  //Then just as many characters of the MD5(pw, salt, pw)  MD5_Init(&ctx1);  MD5_Update(&ctx1, (unsigned char *)pw, strlen(pw));  MD5_Update(&ctx1, (unsigned char *)sp, sl);  MD5_Update(&ctx1, (unsigned char *)pw, strlen(pw));  MD5_Final(final, &ctx1);  for (pl = strlen(pw); pl > 0; pl -= kHashLen)  {    MD5_Update(&ctx, final,(pl > kHashLen) ? kHashLen : pl);  }  //Don't leave anything around in vm they could use.  memset(final, 0, sizeof(final));  //Then something really weird...  for (i = strlen(pw); i != 0; i >>= 1)  {    if (i & 1) {      MD5_Update(&ctx, final, 1);    }    else {      MD5_Update(&ctx, (unsigned char *)pw, 1);    }  }  /*   * Now make the output string.  We know our limitations, so we   * can use the string routines without bounds checking.   */  strcpy(passwd, dufr_id);  strncat(passwd, sp, sl);  strcat(passwd, "$");  MD5_Final(final, &ctx);  /*   * And now, just to make sure things don't run too fast..   * On a 60 Mhz Pentium this takes 34 msec, so you would   * need 30 seconds to build a 1000 entry dictionary...   */  for (i = 0; i < 1000; i++)  {    MD5_Init(&ctx1);    if (i & 1) {      MD5_Update(&ctx1, (unsigned char *)pw, strlen(pw));    }    else {      MD5_Update(&ctx1, final, kHashLen);    }    if (i % 3) {      MD5_Update(&ctx1, (unsigned char *)sp, sl);    }    if (i % 7) {      MD5_Update(&ctx1, (unsigned char *)pw, strlen(pw));    }    if (i & 1) {      MD5_Update(&ctx1, final, kHashLen);    }    else {      MD5_Update(&ctx1, (unsigned char *)pw, strlen(pw));    }    MD5_Final(final,&ctx1);  }  p = passwd + strlen(passwd);  l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;  l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;  l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;  l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;  l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;  l =                    final[11]                ; to64(p, l, 2); p += 2;  *p = '\0';    //Don't leave anything around in vm they could use.  memset(final, 0, sizeof(final));  strncpy(result, passwd, nbytes - 1);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -