MD5加密及HMAC-MD5加密(VC源代码)

c语言实现hmac-md5(提供完整的、测试通过的例子) 最近工作需要使用hmac-md5算法,网上找的例子都或多或少有问题。但md5可使用的代码好找,而hmac-md5只需要在md5的基础上做些小操作即可。 完整代码如下。 总共三个文件: md5.c: md5算法的具体实现 md5.h: md5算法的头文件 hmac_md5.c :hmac_md5的实现。(包含main,提供测试例子) 检验方法: 可以通过输入同样的密... 阅读详情

开发语言:C/C++

实现功能:

  • MD5加密及HMAC-MD5加密

下载地址:

HMAC-MD5.zip

更新历史:

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

[cpp]  view plain copy
  1. /* ---------------------------------------------------------- 
  2. 文件名称:HMAC_MD5_API.h 
  3.  
  4. 作者:秦建辉 
  5.  
  6. MSN:splashcn@msn.com 
  7.  
  8. 当前版本:V1.1 
  9.  
  10. 历史版本: 
  11.     V1.1    2010年05月08日 
  12.             增加输出BASE64编码字符串接口。 
  13.  
  14.     V1.0    2010年04月15日 
  15.             完成正式版本。 
  16.  
  17. 功能描述: 
  18.     MD5和HMAC-MD5加密 
  19.  
  20. 接口函数: 
  21.     MD5_Hash 
  22.     HMAC_MD5_Hash 
  23.     MD5_BASE64 
  24.     HMAC_MD5_BASE64 
  25.  ------------------------------------------------------------ */  
  26. #pragma once  
  27.   
  28. #include <windows.h>  
  29.   
  30. //-------------------导出函数-------------  
  31. #ifdef __cplusplus  
  32. extern "C"{  
  33. #endif  
  34.   
  35. /* 
  36. 功能:计算输入数据的MD5哈希值 
  37. 入口参数: 
  38.     inputBuffer:输入数据 
  39.     inputCount:输入数据长度(字节数) 
  40.     outputBuffer:输入数据的哈希值 
  41. 返回值: 
  42.     哈希值的有效长度(字节数) 
  43. */  
  44. INT MD5_Hash( const BYTE* inputBuffer, UINT inputCount, BYTE* outputBuffer );  
  45.   
  46. /* 
  47. 功能:计算输入数据的HMAC-MD5哈希值 
  48. 入口参数: 
  49.     inputBuffer:输入数据 
  50.     inputCount:输入数据长度(字节数) 
  51.     userKey:用户密钥 
  52.     UserKeyLen:用户密钥长度 
  53.     outputBuffer:输入数据的哈希值 
  54. 返回值: 
  55.     哈希值的有效长度(字节数) 
  56. */  
  57. INT HMAC_MD5_Hash( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, BYTE* outputBuffer );  
  58.   
  59. /* 
  60. 功能:计算输入数据的MD5哈希值,并转换为BASE64编码字符串输出。 
  61. 入口参数: 
  62.     inputBuffer:输入数据 
  63.     inputCount:输入数据长度(字节数) 
  64.     outputBuffer:MD5哈希值的BASE64编码字符串 
  65. 返回值: 
  66.     BASE64编码字符串长度(字符数),不包括字符串结束符 
  67. */  
  68. INT MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, TCHAR* outputBuffer );  
  69.   
  70. /* 
  71. 功能:计算输入数据的HMAC-MD5哈希值,并转换为BASE64编码字符串输出。 
  72. 入口参数: 
  73.     inputBuffer:输入数据 
  74.     inputCount:输入数据长度(字节数) 
  75.     userKey:用户密钥 
  76.     UserKeyLen:用户密钥长度 
  77.     outputBuffer:HMAC-MD5哈希值的BASE64编码字符串 
  78. 返回值: 
  79.     BASE64编码字符串长度(字符数),不包括字符串结束符 
  80. */  
  81. INT HMAC_MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, TCHAR* outputBuffer );  
  82.   
  83. #ifdef __cplusplus  
  84. }  
  85. #endif  

HMAC_MD5_DATA.h:

[cpp]  view plain copy
  1. #pragma once  
  2.   
  3. typedef struct  
  4. {  
  5.     DWORD   p[4];  
  6.     DWORD   q[4][16];  
  7. } TYPE_MD5DATA;  
  8.   
  9. /* ------------------------------------------------ 
  10.          MD5关键参数,修改即可形成不同的变体 
  11.    ------------------------------------------------ */  
  12. const TYPE_MD5DATA MD5_ARGUMENTS = {  
  13.     // 初始状态  
  14.     {0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476},  
  15.   
  16.     // 变换操作偏移量表  
  17.     {0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,  
  18.      0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,  
  19.      0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,  
  20.      0x6B901122,0xFD987193,0xA679438E,0x49B40821,  
  21.   
  22.      0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,  
  23.      0xD62F105D,0x02441453,0xD8A1E681,0xE7D3FBC8,  
  24.      0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,  
  25.      0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,  
  26.   
  27.      0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,  
  28.      0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,  
  29.      0x289B7EC6,0xEAA127FA,0xD4EF3085,0x04881D05,  
  30.      0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,  
  31.   
  32.      0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,  
  33.      0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,  
  34.      0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,  
  35.      0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391}  
  36. };  
  37.   
  38. // 变换操作移位表  
  39. const BYTE MDShiftTable[][4] = {{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}};  
  40.   
  41. // 填充数据  
  42. const BYTE MDPadding[] = {  
  43.     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
  44.        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
  45.        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
  46.        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  
  47. };  
  48.   
  49. // MD5基本位操作函数  
  50. #define F(x, y, z)  (((x) & (y)) | ((~x) & (z)))  
  51. #define G(x, y, z)  (((x) & (z)) | ((y) & (~z)))  
  52. #define H(x, y, z)  ((x) ^ (y) ^ (z))  
  53. #define I(x, y, z)  ((y) ^ ((x) | (~z)))  
  54.   
  55. // 位循环左移位操作  
  56. #define ROL(x, n)   (((x) << (n)) | ((x) >> (32-(n))))  
  57.   
  58. // ---------变换操作----------  
  59. // 第一轮变换基本操作  
  60. #define FF(a, b, c, d, x, s, t) { /  
  61.     (a) += F((b), (c), (d)) + (x) + (t); /  
  62.     (a) = ROL((a), (s)); /  
  63.     (a) += (b); /  
  64. }  
  65.   
  66. // 第二轮变换基本操作  
  67. #define GG(a, b, c, d, x, s, t) { /  
  68.     (a) += G((b), (c), (d)) + (x) + (t); /  
  69.     (a) = ROL((a), (s)); /  
  70.     (a) += (b); /  
  71. }  
  72.   
  73. // 第三轮变换基本操作  
  74. #define HH(a, b, c, d, x, s, t) { /  
  75.     (a) += H((b), (c), (d)) + (x) + (t); /  
  76.     (a) = ROL((a), (s)); /  
  77.     (a) += (b); /  
  78. }  
  79.   
  80. // 第四轮变换基本操作  
  81. #define II(a, b, c, d, x, s, t) { /  
  82.     (a) += I((b), (c), (d)) + (x) + (t); /  
  83.     (a) = ROL((a), (s)); /  
  84.     (a) += (b); /  
  85. }  

HMAC_MD5_API.cpp:

[cpp]  view plain copy
  1. #include "HMAC_MD5_API.h"  
  2. #include "HMAC_MD5_DATA.h"  
  3. #include "..//BASE64//BASE64_API.h"  
  4.   
  5. // 定义数据结构  
  6. typedef struct _MD5CTX {  
  7.     DWORD   aState[4];      // 记录数据的变化状态  
  8.     DWORD   aCount[2];      // 记录数据的原始长度(以bit为单位)  
  9.     BYTE    aBuffer[64];    // 原始数据  
  10. } MD5CTX;  
  11.   
  12. // 初始化  
  13. void MD5_Init( MD5CTX* pstruContext )  
  14. {  
  15.     const DWORD *MDOriginState;  
  16.   
  17.     MDOriginState = MD5_ARGUMENTS.p;  
  18.     pstruContext->aState[0] = MDOriginState[0];  
  19.     pstruContext->aState[1] = MDOriginState[1];  
  20.     pstruContext->aState[2] = MDOriginState[2];  
  21.     pstruContext->aState[3] = MDOriginState[3];  
  22.     pstruContext->aCount[0] = pstruContext->aCount[1] = 0;  
  23. }  
  24.   
  25. // MD5基本变换操作  
  26. void MD5_Transform( DWORD* pState, DWORD* px )  
  27. {  
  28.     const DWORD (*MDOffTable)[16];  
  29.     DWORD a,b,c,d;  
  30.   
  31.     MDOffTable = MD5_ARGUMENTS.q;  
  32.     a = pState[0], b = pState[1], c = pState[2], d = pState[3];  
  33.   
  34.     // 第一轮变换  
  35.     FF(a, b, c, d, px[ 0], MDShiftTable[0][0], MDOffTable[0][ 0]);  
  36.     FF(d, a, b, c, px[ 1], MDShiftTable[0][1], MDOffTable[0][ 1]);  
  37.     FF(c, d, a, b, px[ 2], MDShiftTable[0][2], MDOffTable[0][ 2]);  
  38.     FF(b, c, d, a, px[ 3], MDShiftTable[0][3], MDOffTable[0][ 3]);  
  39.     FF(a, b, c, d, px[ 4], MDShiftTable[0][0], MDOffTable[0][ 4]);  
  40.     FF(d, a, b, c, px[ 5], MDShiftTable[0][1], MDOffTable[0][ 5]);  
  41.     FF(c, d, a, b, px[ 6], MDShiftTable[0][2], MDOffTable[0][ 6]);  
  42.     FF(b, c, d, a, px[ 7], MDShiftTable[0][3], MDOffTable[0][ 7]);  
  43.     FF(a, b, c, d, px[ 8], MDShiftTable[0][0], MDOffTable[0][ 8]);  
  44.     FF(d, a, b, c, px[ 9], MDShiftTable[0][1], MDOffTable[0][ 9]);  
  45.     FF(c, d, a, b, px[10], MDShiftTable[0][2], MDOffTable[0][10]);  
  46.     FF(b, c, d, a, px[11], MDShiftTable[0][3], MDOffTable[0][11]);  
  47.     FF(a, b, c, d, px[12], MDShiftTable[0][0], MDOffTable[0][12]);  
  48.     FF(d, a, b, c, px[13], MDShiftTable[0][1], MDOffTable[0][13]);  
  49.     FF(c, d, a, b, px[14], MDShiftTable[0][2], MDOffTable[0][14]);  
  50.     FF(b, c, d, a, px[15], MDShiftTable[0][3], MDOffTable[0][15]);  
  51.   
  52.     // 第二轮变换  
  53.     GG(a, b, c, d, px[ 1], MDShiftTable[1][0], MDOffTable[1][ 0]);  
  54.     GG(d, a, b, c, px[ 6], MDShiftTable[1][1], MDOffTable[1][ 1]);  
  55.     GG(c, d, a, b, px[11], MDShiftTable[1][2], MDOffTable[1][ 2]);  
  56.     GG(b, c, d, a, px[ 0], MDShiftTable[1][3], MDOffTable[1][ 3]);  
  57.     GG(a, b, c, d, px[ 5], MDShiftTable[1][0], MDOffTable[1][ 4]);  
  58.     GG(d, a, b, c, px[10], MDShiftTable[1][1], MDOffTable[1][ 5]);  
  59.     GG(c, d, a, b, px[15], MDShiftTable[1][2], MDOffTable[1][ 6]);  
  60.     GG(b, c, d, a, px[ 4], MDShiftTable[1][3], MDOffTable[1][ 7]);  
  61.     GG(a, b, c, d, px[ 9], MDShiftTable[1][0], MDOffTable[1][ 8]);  
  62.     GG(d, a, b, c, px[14], MDShiftTable[1][1], MDOffTable[1][ 9]);  
  63.     GG(c, d, a, b, px[ 3], MDShiftTable[1][2], MDOffTable[1][10]);  
  64.     GG(b, c, d, a, px[ 8], MDShiftTable[1][3], MDOffTable[1][11]);  
  65.     GG(a, b, c, d, px[13], MDShiftTable[1][0], MDOffTable[1][12]);  
  66.     GG(d, a, b, c, px[ 2], MDShiftTable[1][1], MDOffTable[1][13]);  
  67.     GG(c, d, a, b, px[ 7], MDShiftTable[1][2], MDOffTable[1][14]);  
  68.     GG(b, c, d, a, px[12], MDShiftTable[1][3], MDOffTable[1][15]);  
  69.                           
  70.     // 第三轮变换      
  71.     HH(a, b, c, d, px[ 5], MDShiftTable[2][0], MDOffTable[2][ 0]);  
  72.     HH(d, a, b, c, px[ 8], MDShiftTable[2][1], MDOffTable[2][ 1]);  
  73.     HH(c, d, a, b, px[11], MDShiftTable[2][2], MDOffTable[2][ 2]);  
  74.     HH(b, c, d, a, px[14], MDShiftTable[2][3], MDOffTable[2][ 3]);  
  75.     HH(a, b, c, d, px[ 1], MDShiftTable[2][0], MDOffTable[2][ 4]);  
  76.     HH(d, a, b, c, px[ 4], MDShiftTable[2][1], MDOffTable[2][ 5]);  
  77.     HH(c, d, a, b, px[ 7], MDShiftTable[2][2], MDOffTable[2][ 6]);  
  78.     HH(b, c, d, a, px[10], MDShiftTable[2][3], MDOffTable[2][ 7]);  
  79.     HH(a, b, c, d, px[13], MDShiftTable[2][0], MDOffTable[2][ 8]);  
  80.     HH(d, a, b, c, px[ 0], MDShiftTable[2][1], MDOffTable[2][ 9]);  
  81.     HH(c, d, a, b, px[ 3], MDShiftTable[2][2], MDOffTable[2][10]);  
  82.     HH(b, c, d, a, px[ 6], MDShiftTable[2][3], MDOffTable[2][11]);  
  83.     HH(a, b, c, d, px[ 9], MDShiftTable[2][0], MDOffTable[2][12]);  
  84.     HH(d, a, b, c, px[12], MDShiftTable[2][1], MDOffTable[2][13]);  
  85.     HH(c, d, a, b, px[15], MDShiftTable[2][2], MDOffTable[2][14]);  
  86.     HH(b, c, d, a, px[ 2], MDShiftTable[2][3], MDOffTable[2][15]);  
  87.                           
  88.     // 第四轮变换      
  89.     II(a, b, c, d, px[ 0], MDShiftTable[3][0], MDOffTable[3][ 0]);  
  90.     II(d, a, b, c, px[ 7], MDShiftTable[3][1], MDOffTable[3][ 1]);  
  91.     II(c, d, a, b, px[14], MDShiftTable[3][2], MDOffTable[3][ 2]);  
  92.     II(b, c, d, a, px[ 5], MDShiftTable[3][3], MDOffTable[3][ 3]);  
  93.     II(a, b, c, d, px[12], MDShiftTable[3][0], MDOffTable[3][ 4]);  
  94.     II(d, a, b, c, px[ 3], MDShiftTable[3][1], MDOffTable[3][ 5]);  
  95.     II(c, d, a, b, px[10], MDShiftTable[3][2], MDOffTable[3][ 6]);  
  96.     II(b, c, d, a, px[ 1], MDShiftTable[3][3], MDOffTable[3][ 7]);  
  97.     II(a, b, c, d, px[ 8], MDShiftTable[3][0], MDOffTable[3][ 8]);  
  98.     II(d, a, b, c, px[15], MDShiftTable[3][1], MDOffTable[3][ 9]);  
  99.     II(c, d, a, b, px[ 6], MDShiftTable[3][2], MDOffTable[3][10]);  
  100.     II(b, c, d, a, px[13], MDShiftTable[3][3], MDOffTable[3][11]);  
  101.     II(a, b, c, d, px[ 4], MDShiftTable[3][0], MDOffTable[3][12]);  
  102.     II(d, a, b, c, px[11], MDShiftTable[3][1], MDOffTable[3][13]);  
  103.     II(c, d, a, b, px[ 2], MDShiftTable[3][2], MDOffTable[3][14]);  
  104.     II(b, c, d, a, px[ 9], MDShiftTable[3][3], MDOffTable[3][15]);    
  105.   
  106.     pState[0] += a;  
  107.     pState[1] += b;  
  108.     pState[2] += c;  
  109.     pState[3] += d;  
  110. }  
  111.   
  112. // MD5块更新操作  
  113. void MD5_Update( MD5CTX* pstruContext, const BYTE* pInput, DWORD dwInputLen )  
  114. {  
  115.     DWORD i, dwIndex, dwPartLen, dwBitsNum;  
  116.   
  117.     // 计算 mod 64 的字节数  
  118.     dwIndex = (pstruContext->aCount[0] >> 3) & 0x3F;  
  119.   
  120.     // 更新数据位数  
  121.     dwBitsNum = dwInputLen << 3;  
  122.     pstruContext->aCount[0] += dwBitsNum;  
  123.       
  124.     if(pstruContext->aCount[0] < dwBitsNum)  
  125.     {  
  126.         pstruContext->aCount[1]++;  
  127.     }  
  128.   
  129.     pstruContext->aCount[1] += dwInputLen >> 29;  
  130.   
  131.     dwPartLen = 64 - dwIndex;  
  132.     if(dwInputLen >= dwPartLen)  
  133.     {  
  134.         memcpy( pstruContext->aBuffer+dwIndex, pInput, dwPartLen );  
  135.         MD5_Transform( pstruContext->aState, (DWORD*)pstruContext->aBuffer );  
  136.   
  137.         for(i = dwPartLen; i + 63 < dwInputLen; i += 64 )  
  138.         {  
  139.             MD5_Transform( pstruContext->aState, (DWORD*)(pInput + i) );  
  140.         }  
  141.   
  142.         dwIndex = 0;  
  143.     }  
  144.     else  
  145.     {  
  146.         i = 0;  
  147.     }  
  148.   
  149.     memcpy( pstruContext->aBuffer + dwIndex, pInput + i, dwInputLen - i );  
  150. }  
  151.   
  152. // 处理最后的数据块  
  153. void MD5_Final( MD5CTX* pstruContext )  
  154. {  
  155.     DWORD dwIndex, dwPadLen;  
  156.     BYTE pBits[8];  
  157.       
  158.     memcpy( pBits, pstruContext->aCount, 8 );  
  159.       
  160.     // 计算 mod 64 的字节数  
  161.     dwIndex = (pstruContext->aCount[0] >> 3) & 0x3F;  
  162.   
  163.     // 使长度满足K*64+56个字节  
  164.     dwPadLen = (dwIndex < 56) ? (56-dwIndex) : (120-dwIndex);  
  165.     MD5_Update( pstruContext, MDPadding, dwPadLen );  
  166.     MD5_Update( pstruContext, pBits, 8 );  
  167. }  
  168.   
  169. INT MD5_Hash( const BYTE* inputBuffer, UINT inputCount, BYTE* outputBuffer )  
  170. {  
  171.     MD5CTX struContext;  
  172.       
  173.     if( inputBuffer == NULL )  
  174.     {  
  175.         inputCount = 0;  
  176.     }  
  177.   
  178.     // 进行MD5变换  
  179.     MD5_Init( &struContext );       // 初始化  
  180.     MD5_Update( &struContext, inputBuffer, inputCount );    // MD5数据块更新操作  
  181.     MD5_Final( &struContext );  // 获得最终结果  
  182.   
  183.     // 获取哈希值  
  184.     if( outputBuffer != NULL )  
  185.     {  
  186.         memcpy( outputBuffer, struContext.aState, 16 );  
  187.     }     
  188.   
  189.     return 16;  
  190. }  
  191.   
  192. INT HMAC_MD5_Hash( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, BYTE* outputBuffer )  
  193. {     
  194.     BYTE hmacKey[64] = {0};  
  195.     BYTE k_ipad[64];  
  196.     BYTE k_opad[64];  
  197.     MD5CTX struContext;  
  198.   
  199.     if( inputBuffer == NULL )  
  200.     {  
  201.         inputCount = 0;  
  202.     }  
  203.   
  204.     if( userKey == NULL )  
  205.     {  
  206.         UserKeyLen = 0;  
  207.     }  
  208.   
  209.     // 保证密钥长度不超过64字节  
  210.     if( UserKeyLen > 64 )  
  211.     {  
  212.          MD5_Hash( userKey, UserKeyLen, hmacKey );  
  213.     }  
  214.     else  
  215.     {  
  216.         memcpy( hmacKey, userKey, UserKeyLen );  
  217.     }  
  218.   
  219.     for( UINT i = 0; i < 64; i++ )  
  220.     {  
  221.         k_ipad[i] = hmacKey[i] ^ 0x36;  
  222.         k_opad[i] = hmacKey[i] ^ 0x5C;  
  223.     }  
  224.   
  225.     // 内圈MD5运算  
  226.     MD5_Init( &struContext );       // 初始化  
  227.     MD5_Update( &struContext, k_ipad, 64 ); // MD5数据块更新操作  
  228.     MD5_Update( &struContext, inputBuffer, inputCount );    // MD5数据块更新操作  
  229.     MD5_Final( &struContext );  // 获得最终结果  
  230.     memcpy( hmacKey, struContext.aState, 16 );  
  231.   
  232.     // 外圈MD5运算  
  233.     MD5_Init( &struContext );       // 初始化  
  234.     MD5_Update( &struContext, k_opad, 64 ); // MD5数据块更新操作  
  235.     MD5_Update( &struContext, hmacKey, 16 );    // MD5数据块更新操作  
  236.     MD5_Final( &struContext );  // 获得最终结果  
  237.   
  238.     // 获取哈希值  
  239.     if( outputBuffer != NULL )  
  240.     {  
  241.         memcpy( outputBuffer, struContext.aState, 16 );  
  242.     }     
  243.   
  244.     return 16;  
  245. }  
  246.   
  247. INT MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, TCHAR* outputBuffer )  
  248. {  
  249.     BYTE hash[16];  
  250.     INT iByteNum;  
  251.   
  252.     // 计算输入串MD5的哈希值  
  253.     iByteNum = MD5_Hash( inputBuffer, inputCount, hash );  
  254.   
  255.     // 将哈希值转换成BASE64编码  
  256.     return BASE64_Encode( hash, iByteNum, outputBuffer );  
  257. }  
  258.   
  259. INT HMAC_MD5_BASE64( const BYTE* inputBuffer, UINT inputCount, const BYTE* userKey, UINT UserKeyLen, TCHAR* outputBuffer )  
  260. {  
  261.     BYTE hash[16];  
  262.     INT iByteNum;  
  263.   
  264.     // 计算输入串HMAC-MD5的哈希值  
  265.     iByteNum = HMAC_MD5_Hash( inputBuffer, inputCount, userKey, UserKeyLen, hash );  
  266.   
  267.     // 将哈希值转换成BASE64编码  
  268.     return BASE64_Encode( hash, iByteNum, outputBuffer );  
  269. }  

VC++加密算法代码库:从AES到RSA的200+实现与实战指南 加密算法是保障数据安全的核心技术,其原理基于数学变换将明文转换为不可读的密文,防止未授权访问。在软件开发中,加密技术对保护用户隐私、确保通信安全具有关键价值,广泛应用于文件加密、网络传输、身份认证等场景。本文聚焦于VC++环境下的加密算法实现,针对AES对称加密和RSA非对称加密等常见需求,提供了可直接集成的代码库与工程实践方案,帮助开发者快速构建安全可靠的桌面应用。 阅读详情

相关推荐

从零手写一个可靠的软件序列号生成器:HMAC与Base32编码实践

在软件分发与商业化运营中,如何设计一套安全、易用的离线授权机制是开发者经常面对的挑战。序列号作为一种“可验证的编码”,既需要保证内容不可伪造,又要兼顾用户手工输入的体验。本文从数字签名与编码原理出发,介绍了基于HMAC-SHA256与Base32字符集的序列号生成方案,涵盖格式设计、签名截断、双层校验、密钥隔离等关键环节。同时讨论了时间容差、批量生成、错误提示等工程实践细节,帮助开发者在无网络环境下实现可靠的软件授权与防盗版。通过合理的密钥管理与非对称签名扩展,该方案可平滑演进到更高安全级别的授权体系。

weixin_34005042的博客 400

MD5和SHA1算法C++实现及运行时间分析

1.MD5代码实现 HMAC.H即MD5头文件。 #ifndef HMAC_H #define HMAC_H // POINTER defines a generic pointer type typedef unsigned char *POINTER; // UINT2 defines a two byte word typedef unsigned short int UINT2

3348

HMAC-MD5加密C++源码

HMACMD5 是从 MD5 哈希函数构造的一种键控哈希算法,被用作基于哈希的消息验证代码 (HMAC)。此 HMAC 进程将密钥与消息数据混合,使用哈希函数对混合结果进行哈希计算,将所得哈希值与该密钥混合,然后再次应用哈希函数。输出的哈希值长度为 128 位。

c++ 修改文件摘要信息_Java加密与解密之消息摘要算法1

消息摘要算法有3大类,分别是:MD、SHA、MAC,通常用于数据完整性的验证。MD:Message Digest消息摘要算法。包括:MD2,MD4,MD5 3种算法。SHA:Secure Hash Algorithm安全散列算法。包括:SHA-1和SHA-2系列,包含了SHA-224,SHA-256,SHA-384,SHA-512。Hmac:Message Authentication Code消...

weixin_39843338的博客 216

c++编写的hmac-md5

基于C++编写的,hmac-md5算法,经过测试~~

MD5和HMACMD5 C语言实现,亲测有效

MD5和 HMAC-MD5 C 语言实现,在前人的基础上修改的,可用于嵌入式等各种需要使用md5或者mac-md5的c语言场景,亲测编译通过且验证有效。

md5-hmac 算法实现(收集网络中好的代码)

【代码】md5-hmac 算法实现(收集网络中好的代码)

kevinwangshilin的博客 235

汇川机器人与PLC通信-ModbusTCP超详细案例

通过汇川机器人与PLC的ModbusTCP通信项目案例,我们可以了解通讯配置的过程,地址映射的方式,对接信号的转换,运行时序的逻辑等注意事项,帮助我们快速应用到项目中。

weixin_44166380的博客 1万+

MD5加密及HMAC-MD5加密(VC源代码

开发语言:C/C++实现功能:MD5加密及HMAC-MD5加密下载地址:HMAC-MD5.zip更新历史:V1.1 2010年05月08日增加输出BASE64编码字符串接口。V1.0 2010年04月15日完成正式版本。接口函数:MD5_HashHMAC_MD5_HashMD5_

求索 2807

数据驱动的细胞动力学:从高通量成像到机器学习预测的完整实践指南

细胞动力学研究细胞群体随时间变化的规律和命运决策机制,是理解生命过程的基础。其核心原理在于将传统的定性观察转化为定量分析,通过高通量成像、单细胞测序等技术获取多维时序数据,并运用机器学习与统计模型挖掘数据中的深层模式。这一技术价值在于实现从“描述现象”到“预测行为”的范式转变,显著提升研究的客观性和可重复性。在应用场景上,它广泛应用于药物筛选、疾病机制研究和发育生物学等领域,能够加速靶点发现和疗效评估。本文聚焦于数据驱动的细胞动力学分析,详细拆解了从实验设计、图像处理、单细胞追踪到特征工程与建模预测的端到端

weixin_29056781的博客 268

【数据库】SQL Server 2008 R2 安装全流程详解与常见问题避坑指南

本文详细解析了SQL Server 2008 R2的完整安装流程与核心配置。从安装前的系统兼容性检查、.NET Framework依赖准备,到图文详解实例配置、混合身份验证模式设置等关键步骤,并提供了安装失败、服务无法启动等高频问题的排查与避坑指南,帮助用户顺利完成部署。

java5的博客 1241

hmac md5 c php,MD5加密及HMAC-MD5加密(VC源代码) | 学步园

#include"HMAC_MD5_API.h"#include"HMAC_MD5_DATA.h"#include"..//BASE64//BASE64_API.h"//定义数据结构typedefstruct_MD5CTX{DWORDaState[4];//记录数据的变化状态DWORDaCount[2];//记录数据的原始长度(以bit为单位)BYTEaBuffer[64];//原...

weixin_33683108的博客 401

项目经理必看:如何建立高效的相关方沟通机制?

你是否遇到过这样的场景?客户突然说“这不是我要的”,开发团队抱怨“需求总变”,高层追问“进度滞后为什么不早说”?这些问题的根源往往是——相关方沟通机制失效。本文聚焦“如何建立高效沟通机制”,覆盖从识别相关方到持续优化的全流程,适用于IT、产品、工程等各类项目。本文将按“理解问题→拆解核心概念→掌握工具方法→实战落地→未来趋势”的逻辑展开,重点讲解“相关方分析矩阵”“沟通计划表”等实用工具,并用“组织生日派对”的案例贯穿全文,让抽象概念变得可感知。相关方识别:用“权力/利益矩阵”找对人(像派对邀请关键客人)

项目管理的博客 1295

C++实现MD5加密

c++的md5加密,如果字符串中有转义字符,不会转义以后再加密,要手动转义; 下面是头文件 md5.h //MD5.h #ifndef BZF_MD5_H #define BZF_MD5_H #include #include // a small class for calculating MD5 hashes of strings or byte arra

qq_29350467的博客 1150

数据处理和分析之数据聚类:层次聚类(Hierarchical Clustering):单链接层次聚类方法

单链接层次聚类(Single-Linkage Hierarchical Clustering)是凝聚型层次聚类的一种,它基于数据点之间的最小距离来定义聚类间的相似性。在单链接层次聚类中,两个聚类之间的距离定义为这两个聚类中任意两个数据点之间的最短距离。这种聚类方法倾向于形成链状或线性的聚类,因为聚类的边界是由最远的数据点决定的,而不是聚类的平均或中心位置。单链接层次聚类通过计算簇间最近点的距离来决定簇的合并,这种方法简单直观,但可能导致簇的形状不规则,尤其是在数据点分布不均匀的情况下。

2401_87715305的博客 1442

TIA博途选型工具Selection Tool的基本使用方法介绍

TIA博途选型工具Selection Tool的基本使用方法介绍

Robot_PLC_HMI_Automation 4209

方案集成-采用配置文件实现多个软件对多个硬件的加密

通过前面的文章,我们已经掌握了如下5项技术:通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号MD5加密及HMAC-MD5加密(VC源代码)BASE64编码和解码(VC源代码)基于内存映射文件方式读写ini文件现在我将综合这5项技

秦建辉的专栏 1960

高通Camx功能feature分析之十:高通NCS服务之注册和启动

本文介绍了高通NCS(非相机传感器)服务的注册与启动流程。NCS通过QMI接口访问陀螺仪等传感器,为相机EIS/AEC等功能提供辅助数据。文章详细解析了服务注册时的QueryCapabilites能力查询、RegisterService注册流程,以及通过StartNCSService启动服务线程的过程。重点包括:1)AF/EIS等节点通过NCSService创建传感器对象;2)注册时需校验传感器类型和接口;3)首次注册成功后会启动NCS服务线程;4)采样率变化时需重新配置会话。通过线程池管理实现传感器数据的

1261

Python RSA加密模拟登录

杂项之python利用pycrypto实现RSA 本节内容 pycrypto模块简介 RSA的公私钥生成 RSA使用公钥加密数据 RSA使用私钥解密密文 破解博客园登陆 pycrypto模块简介 pycrypto模块是python中用来处理加密解密等信息安全相关的一个很重要模块。 该模块支持的加密方式: 对称加密方式: AES DES ARC4 散列值计...

Reach Higher 3047

【系统架构设计师-2024下半年真题】案例分析-参考答案及部分详解(完整回忆版)

根据h中描述,为了保证高可靠性,有ping/echo,心跳机制两种策略,从资源利用率问为啥心跳更好。王工觉得使用ping/echo好,但李工觉得从系统资源利用率来说,使用心跳机制好 1、针对质量属性可以使用ping/echo和心跳模式实现,分别简述ping/echo和心跳的实现原理。 2、张工认为心跳策略比较适合,简述为什么?

数据知道的博客 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

c c++ php常用的加密解密算法

2020年9月20日13:04:47 为什么需要加密解密算法? 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码为“密文”, 使其只能在输入相应的密钥之后才能显示出原容,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。 该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程。 比如api接口,数据传输,用户密码加密等、 php常用算法 环境 ...

Z.X的博客 415

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Delphi7调用动态库实现HMACSHA编码资源文件:高效加密解决方案

Delphi7调用动态库实现HMACSHA编码资源文件:高效加密解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在当今信息安全日益重要的背景下,数据加密成为了软件开发中不可或缺的一部分。Delphi7作为一款经典编程语言,虽然提供了基础的加密功能,但在实现HMACSHA编码方面却并不简便。本项目正是为了解决这一痛点而诞生,它通过调用动态库,实现了在Delphi...

gitblog_06771的博客 412

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

如何让文档库永不过期:haiku.rag多数据源监控、增量更新与死信队列重试机制解析

haiku.rag 是一个面向本地与自托管场景的 Agentic RAG 项目,支持混合检索、重排与多模态文档问答。它的长期价值不止于"问答"——内置的 `haiku-ingester` 服务会持续**监控文件系统、S3、HTTP、WebDAV 等多种数据源**,只把"变了的那部分"做**增量更新**,而对反复失败的任务提供**指数退避重试**与**死信队列(Dead-Letter Queue)*

gitblog_01174的博客 205

如何构建高可用分布式网络监控:SmokePing主从架构深度解析

在当今复杂的网络环境中,企业面临着从单一数据中心到全球分布式架构的监控挑战。传统的集中式监控方案难以应对多地域、多节点的网络性能监测需求,而SmokePing作为业界领先的延迟监测和图形化系统,通过其强大的主从架构设计,为大规模网络监控提供了专业级解决方案。本文将深入探讨SmokePing主从架构的核心原理、实施步骤和最佳实践。 ## 挑战与需求:大规模网络监控的痛点 ### 传统监控方案的局

gitblog_00159的博客 151

VC++网络安全编程范例(7)-实现哈希摘要算法

哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据...

chengyixian7877的博客 71
上一篇: BASE64编码和解码(VC源代码)
下一篇: VC实现重启TP-LINK路由器
M-先生
博客等级 码龄17年 60粉丝 6原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值