开发语言:C/C++
实现功能:
- MD5加密及HMAC-MD5加密
下载地址:
V1.1 2010年05月08日
- 增加输出BASE64编码字符串接口。
V1.0 2010年04月15日
完成正式版本。
接口函数:
MD5_Hash
HMAC_MD5_Hash
MD5_BASE64
HMAC_MD5_BASE64
源文件:
HMAC_MD5_API.h
- /* ----------------------------------------------------------
- 文件名称:HMAC_MD5_API.h
- 作者:秦建辉
- MSN:splashcn@msn.com
- 当前版本:V1.1
- 历史版本:
- V1.1 2010年05月08日
- 增加输出BASE64编码字符串接口。
- V1.0 2010年04月15日
- 完成正式版本。
- 功能描述:
- MD5和HMAC-MD5加密
- 接口函数:
- MD5_Hash
- HMAC_MD5_Hash
- MD5_BASE64
- HMAC_MD5_BASE64
- ------------------------------------------------------------ */
- #pragma once
- #include <windows.h>
- //-------------------导出函数-------------
- #ifdef __cplusplus
- extern "C"{
- #endif
- /*
- 功能:计算输入数据的MD5哈希值
- 入口参数:
- inputBuffer:输入数据
- inputCount:输入数据长度(字节数)
- outputBuffer:输入数据的哈希值
- 返回值:
- 哈希值的有效长度(字节数)
- */
- INT MD5_Hash( const BYTE* inputBuffer, UINT inputCount, BYTE* outputBuffer );
- /*
- 功能:计算输入数据的HMAC-MD5哈希值
- 入口参数:
- inputBuffer:输入数据
- inputCount:输入数据长度(字节数)
- userKey:用户密钥
- UserKeyLen:用户密钥长度
- outputBuffer:输入数据的哈希值
- 返回值:
- 哈希值的有效长度(字节数)
- */
- INT HMAC_MD5_Hash( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, BYTE* outputBuffer );
- /*
- 功能:计算输入数据的MD5哈希值,并转换为BASE64编码字符串输出。
- 入口参数:
- inputBuffer:输入数据
- inputCount:输入数据长度(字节数)
- outputBuffer:MD5哈希值的BASE64编码字符串
- 返回值:
- BASE64编码字符串长度(字符数),不包括字符串结束符
- */
- INT MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, TCHAR* outputBuffer );
- /*
- 功能:计算输入数据的HMAC-MD5哈希值,并转换为BASE64编码字符串输出。
- 入口参数:
- inputBuffer:输入数据
- inputCount:输入数据长度(字节数)
- userKey:用户密钥
- UserKeyLen:用户密钥长度
- outputBuffer:HMAC-MD5哈希值的BASE64编码字符串
- 返回值:
- BASE64编码字符串长度(字符数),不包括字符串结束符
- */
- INT HMAC_MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, TCHAR* outputBuffer );
- #ifdef __cplusplus
- }
- #endif
HMAC_MD5_DATA.h:
- #pragma once
- typedef struct
- {
- DWORD p[4];
- DWORD q[4][16];
- } TYPE_MD5DATA;
- /* ------------------------------------------------
- MD5关键参数,修改即可形成不同的变体
- ------------------------------------------------ */
- const TYPE_MD5DATA MD5_ARGUMENTS = {
- // 初始状态
- {0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476},
- // 变换操作偏移量表
- {0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,
- 0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,
- 0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,
- 0x6B901122,0xFD987193,0xA679438E,0x49B40821,
- 0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,
- 0xD62F105D,0x02441453,0xD8A1E681,0xE7D3FBC8,
- 0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,
- 0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,
- 0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,
- 0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,
- 0x289B7EC6,0xEAA127FA,0xD4EF3085,0x04881D05,
- 0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,
- 0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,
- 0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,
- 0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,
- 0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391}
- };
- // 变换操作移位表
- const BYTE MDShiftTable[][4] = {{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}};
- // 填充数据
- const BYTE MDPadding[] = {
- 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
- };
- // MD5基本位操作函数
- #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 ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
- // ---------变换操作----------
- // 第一轮变换基本操作
- #define FF(a, b, c, d, x, s, t) { /
- (a) += F((b), (c), (d)) + (x) + (t); /
- (a) = ROL((a), (s)); /
- (a) += (b); /
- }
- // 第二轮变换基本操作
- #define GG(a, b, c, d, x, s, t) { /
- (a) += G((b), (c), (d)) + (x) + (t); /
- (a) = ROL((a), (s)); /
- (a) += (b); /
- }
- // 第三轮变换基本操作
- #define HH(a, b, c, d, x, s, t) { /
- (a) += H((b), (c), (d)) + (x) + (t); /
- (a) = ROL((a), (s)); /
- (a) += (b); /
- }
- // 第四轮变换基本操作
- #define II(a, b, c, d, x, s, t) { /
- (a) += I((b), (c), (d)) + (x) + (t); /
- (a) = ROL((a), (s)); /
- (a) += (b); /
- }
HMAC_MD5_API.cpp:
- #include "HMAC_MD5_API.h"
- #include "HMAC_MD5_DATA.h"
- #include "..//BASE64//BASE64_API.h"
- // 定义数据结构
- typedef struct _MD5CTX {
- DWORD aState[4]; // 记录数据的变化状态
- DWORD aCount[2]; // 记录数据的原始长度(以bit为单位)
- BYTE aBuffer[64]; // 原始数据
- } MD5CTX;
- // 初始化
- void MD5_Init( MD5CTX* pstruContext )
- {
- const DWORD *MDOriginState;
- MDOriginState = MD5_ARGUMENTS.p;
- pstruContext->aState[0] = MDOriginState[0];
- pstruContext->aState[1] = MDOriginState[1];
- pstruContext->aState[2] = MDOriginState[2];
- pstruContext->aState[3] = MDOriginState[3];
- pstruContext->aCount[0] = pstruContext->aCount[1] = 0;
- }
- // MD5基本变换操作
- void MD5_Transform( DWORD* pState, DWORD* px )
- {
- const DWORD (*MDOffTable)[16];
- DWORD a,b,c,d;
- MDOffTable = MD5_ARGUMENTS.q;
- a = pState[0], b = pState[1], c = pState[2], d = pState[3];
- // 第一轮变换
- FF(a, b, c, d, px[ 0], MDShiftTable[0][0], MDOffTable[0][ 0]);
- FF(d, a, b, c, px[ 1], MDShiftTable[0][1], MDOffTable[0][ 1]);
- FF(c, d, a, b, px[ 2], MDShiftTable[0][2], MDOffTable[0][ 2]);
- FF(b, c, d, a, px[ 3], MDShiftTable[0][3], MDOffTable[0][ 3]);
- FF(a, b, c, d, px[ 4], MDShiftTable[0][0], MDOffTable[0][ 4]);
- FF(d, a, b, c, px[ 5], MDShiftTable[0][1], MDOffTable[0][ 5]);
- FF(c, d, a, b, px[ 6], MDShiftTable[0][2], MDOffTable[0][ 6]);
- FF(b, c, d, a, px[ 7], MDShiftTable[0][3], MDOffTable[0][ 7]);
- FF(a, b, c, d, px[ 8], MDShiftTable[0][0], MDOffTable[0][ 8]);
- FF(d, a, b, c, px[ 9], MDShiftTable[0][1], MDOffTable[0][ 9]);
- FF(c, d, a, b, px[10], MDShiftTable[0][2], MDOffTable[0][10]);
- FF(b, c, d, a, px[11], MDShiftTable[0][3], MDOffTable[0][11]);
- FF(a, b, c, d, px[12], MDShiftTable[0][0], MDOffTable[0][12]);
- FF(d, a, b, c, px[13], MDShiftTable[0][1], MDOffTable[0][13]);
- FF(c, d, a, b, px[14], MDShiftTable[0][2], MDOffTable[0][14]);
- FF(b, c, d, a, px[15], MDShiftTable[0][3], MDOffTable[0][15]);
- // 第二轮变换
- GG(a, b, c, d, px[ 1], MDShiftTable[1][0], MDOffTable[1][ 0]);
- GG(d, a, b, c, px[ 6], MDShiftTable[1][1], MDOffTable[1][ 1]);
- GG(c, d, a, b, px[11], MDShiftTable[1][2], MDOffTable[1][ 2]);
- GG(b, c, d, a, px[ 0], MDShiftTable[1][3], MDOffTable[1][ 3]);
- GG(a, b, c, d, px[ 5], MDShiftTable[1][0], MDOffTable[1][ 4]);
- GG(d, a, b, c, px[10], MDShiftTable[1][1], MDOffTable[1][ 5]);
- GG(c, d, a, b, px[15], MDShiftTable[1][2], MDOffTable[1][ 6]);
- GG(b, c, d, a, px[ 4], MDShiftTable[1][3], MDOffTable[1][ 7]);
- GG(a, b, c, d, px[ 9], MDShiftTable[1][0], MDOffTable[1][ 8]);
- GG(d, a, b, c, px[14], MDShiftTable[1][1], MDOffTable[1][ 9]);
- GG(c, d, a, b, px[ 3], MDShiftTable[1][2], MDOffTable[1][10]);
- GG(b, c, d, a, px[ 8], MDShiftTable[1][3], MDOffTable[1][11]);
- GG(a, b, c, d, px[13], MDShiftTable[1][0], MDOffTable[1][12]);
- GG(d, a, b, c, px[ 2], MDShiftTable[1][1], MDOffTable[1][13]);
- GG(c, d, a, b, px[ 7], MDShiftTable[1][2], MDOffTable[1][14]);
- GG(b, c, d, a, px[12], MDShiftTable[1][3], MDOffTable[1][15]);
- // 第三轮变换
- HH(a, b, c, d, px[ 5], MDShiftTable[2][0], MDOffTable[2][ 0]);
- HH(d, a, b, c, px[ 8], MDShiftTable[2][1], MDOffTable[2][ 1]);
- HH(c, d, a, b, px[11], MDShiftTable[2][2], MDOffTable[2][ 2]);
- HH(b, c, d, a, px[14], MDShiftTable[2][3], MDOffTable[2][ 3]);
- HH(a, b, c, d, px[ 1], MDShiftTable[2][0], MDOffTable[2][ 4]);
- HH(d, a, b, c, px[ 4], MDShiftTable[2][1], MDOffTable[2][ 5]);
- HH(c, d, a, b, px[ 7], MDShiftTable[2][2], MDOffTable[2][ 6]);
- HH(b, c, d, a, px[10], MDShiftTable[2][3], MDOffTable[2][ 7]);
- HH(a, b, c, d, px[13], MDShiftTable[2][0], MDOffTable[2][ 8]);
- HH(d, a, b, c, px[ 0], MDShiftTable[2][1], MDOffTable[2][ 9]);
- HH(c, d, a, b, px[ 3], MDShiftTable[2][2], MDOffTable[2][10]);
- HH(b, c, d, a, px[ 6], MDShiftTable[2][3], MDOffTable[2][11]);
- HH(a, b, c, d, px[ 9], MDShiftTable[2][0], MDOffTable[2][12]);
- HH(d, a, b, c, px[12], MDShiftTable[2][1], MDOffTable[2][13]);
- HH(c, d, a, b, px[15], MDShiftTable[2][2], MDOffTable[2][14]);
- HH(b, c, d, a, px[ 2], MDShiftTable[2][3], MDOffTable[2][15]);
- // 第四轮变换
- II(a, b, c, d, px[ 0], MDShiftTable[3][0], MDOffTable[3][ 0]);
- II(d, a, b, c, px[ 7], MDShiftTable[3][1], MDOffTable[3][ 1]);
- II(c, d, a, b, px[14], MDShiftTable[3][2], MDOffTable[3][ 2]);
- II(b, c, d, a, px[ 5], MDShiftTable[3][3], MDOffTable[3][ 3]);
- II(a, b, c, d, px[12], MDShiftTable[3][0], MDOffTable[3][ 4]);
- II(d, a, b, c, px[ 3], MDShiftTable[3][1], MDOffTable[3][ 5]);
- II(c, d, a, b, px[10], MDShiftTable[3][2], MDOffTable[3][ 6]);
- II(b, c, d, a, px[ 1], MDShiftTable[3][3], MDOffTable[3][ 7]);
- II(a, b, c, d, px[ 8], MDShiftTable[3][0], MDOffTable[3][ 8]);
- II(d, a, b, c, px[15], MDShiftTable[3][1], MDOffTable[3][ 9]);
- II(c, d, a, b, px[ 6], MDShiftTable[3][2], MDOffTable[3][10]);
- II(b, c, d, a, px[13], MDShiftTable[3][3], MDOffTable[3][11]);
- II(a, b, c, d, px[ 4], MDShiftTable[3][0], MDOffTable[3][12]);
- II(d, a, b, c, px[11], MDShiftTable[3][1], MDOffTable[3][13]);
- II(c, d, a, b, px[ 2], MDShiftTable[3][2], MDOffTable[3][14]);
- II(b, c, d, a, px[ 9], MDShiftTable[3][3], MDOffTable[3][15]);
- pState[0] += a;
- pState[1] += b;
- pState[2] += c;
- pState[3] += d;
- }
- // MD5块更新操作
- void MD5_Update( MD5CTX* pstruContext, const BYTE* pInput, DWORD dwInputLen )
- {
- DWORD i, dwIndex, dwPartLen, dwBitsNum;
- // 计算 mod 64 的字节数
- dwIndex = (pstruContext->aCount[0] >> 3) & 0x3F;
- // 更新数据位数
- dwBitsNum = dwInputLen << 3;
- pstruContext->aCount[0] += dwBitsNum;
- if(pstruContext->aCount[0] < dwBitsNum)
- {
- pstruContext->aCount[1]++;
- }
- pstruContext->aCount[1] += dwInputLen >> 29;
- dwPartLen = 64 - dwIndex;
- if(dwInputLen >= dwPartLen)
- {
- memcpy( pstruContext->aBuffer+dwIndex, pInput, dwPartLen );
- MD5_Transform( pstruContext->aState, (DWORD*)pstruContext->aBuffer );
- for(i = dwPartLen; i + 63 < dwInputLen; i += 64 )
- {
- MD5_Transform( pstruContext->aState, (DWORD*)(pInput + i) );
- }
- dwIndex = 0;
- }
- else
- {
- i = 0;
- }
- memcpy( pstruContext->aBuffer + dwIndex, pInput + i, dwInputLen - i );
- }
- // 处理最后的数据块
- void MD5_Final( MD5CTX* pstruContext )
- {
- DWORD dwIndex, dwPadLen;
- BYTE pBits[8];
- memcpy( pBits, pstruContext->aCount, 8 );
- // 计算 mod 64 的字节数
- dwIndex = (pstruContext->aCount[0] >> 3) & 0x3F;
- // 使长度满足K*64+56个字节
- dwPadLen = (dwIndex < 56) ? (56-dwIndex) : (120-dwIndex);
- MD5_Update( pstruContext, MDPadding, dwPadLen );
- MD5_Update( pstruContext, pBits, 8 );
- }
- INT MD5_Hash( const BYTE* inputBuffer, UINT inputCount, BYTE* outputBuffer )
- {
- MD5CTX struContext;
- if( inputBuffer == NULL )
- {
- inputCount = 0;
- }
- // 进行MD5变换
- MD5_Init( &struContext ); // 初始化
- MD5_Update( &struContext, inputBuffer, inputCount ); // MD5数据块更新操作
- MD5_Final( &struContext ); // 获得最终结果
- // 获取哈希值
- if( outputBuffer != NULL )
- {
- memcpy( outputBuffer, struContext.aState, 16 );
- }
- return 16;
- }
- INT HMAC_MD5_Hash( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, BYTE* outputBuffer )
- {
- BYTE hmacKey[64] = {0};
- BYTE k_ipad[64];
- BYTE k_opad[64];
- MD5CTX struContext;
- if( inputBuffer == NULL )
- {
- inputCount = 0;
- }
- if( userKey == NULL )
- {
- UserKeyLen = 0;
- }
- // 保证密钥长度不超过64字节
- if( UserKeyLen > 64 )
- {
- MD5_Hash( userKey, UserKeyLen, hmacKey );
- }
- else
- {
- memcpy( hmacKey, userKey, UserKeyLen );
- }
- for( UINT i = 0; i < 64; i++ )
- {
- k_ipad[i] = hmacKey[i] ^ 0x36;
- k_opad[i] = hmacKey[i] ^ 0x5C;
- }
- // 内圈MD5运算
- MD5_Init( &struContext ); // 初始化
- MD5_Update( &struContext, k_ipad, 64 ); // MD5数据块更新操作
- MD5_Update( &struContext, inputBuffer, inputCount ); // MD5数据块更新操作
- MD5_Final( &struContext ); // 获得最终结果
- memcpy( hmacKey, struContext.aState, 16 );
- // 外圈MD5运算
- MD5_Init( &struContext ); // 初始化
- MD5_Update( &struContext, k_opad, 64 ); // MD5数据块更新操作
- MD5_Update( &struContext, hmacKey, 16 ); // MD5数据块更新操作
- MD5_Final( &struContext ); // 获得最终结果
- // 获取哈希值
- if( outputBuffer != NULL )
- {
- memcpy( outputBuffer, struContext.aState, 16 );
- }
- return 16;
- }
- INT MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, TCHAR* outputBuffer )
- {
- BYTE hash[16];
- INT iByteNum;
- // 计算输入串MD5的哈希值
- iByteNum = MD5_Hash( inputBuffer, inputCount, hash );
- // 将哈希值转换成BASE64编码
- return BASE64_Encode( hash, iByteNum, outputBuffer );
- }
- INT HMAC_MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, TCHAR* outputBuffer )
- {
- BYTE hash[16];
- INT iByteNum;
- // 计算输入串HMAC-MD5的哈希值
- iByteNum = HMAC_MD5_Hash( inputBuffer, inputCount, userKey, UserKeyLen, hash );
- // 将哈希值转换成BASE64编码
- return BASE64_Encode( hash, iByteNum, outputBuffer );
- }