最近游戏后台接入腾讯敏感词接口: /v3/user/uic_filter 需要加密方式是hmac_sha1,项目中没有,于是从网上找了库,最后上线应用。说下具体流程和注意的坑:
关键的函数:HMAC_SHA1
注意的点:mars_https::BYTE digest[20];这里数组一定要是20
最终要经过另一个函数调用洗礼:byteToHexStr
以下是测试代码和库函数。
1 #include <iostream> 2 #include <math.h> 3 #include "HmacSha1.h" 4 #include <string> 5 using namespace std; 6 7 string byteToHexStr(unsigned char byte_arr[], int arr_len) 8 { 9 string hexstr; 10 for (int i=0;i<arr_len;i++) 11 { 12 char hex1; 13 char hex2; 14 int value=byte_arr[i]; 15 int v1=value/16; 16 int v2=value % 16; 17 18 //将商转成字母 19 if (v1>=0&&v1<=9) 20 hex1=(char)(48+v1); 21 else 22 hex1=(char)(55+v1); 23 24 //将余数转成字母 25 if (v2>=0&&v2<=9) 26 hex2=(char)(48+v2); 27 else 28 hex2=(char)(55+v2); 29 30 //将字母连接成串 31 hexstr=hexstr+hex1+hex2; 32 } 33 return hexstr; 34 } 35 int main() 36 { 37 string strJoin = "POST&%2Fv3%2Fuser%2Fuic_filter&appid%3D1105752926%26openid%3D33FA239D835DADB54CC6E06D100AB989%26openkey%3DAFE95D97DF01E8DC8F7C75E1041AD1E2"; 38 string strKey = "0aYIIoABlh3VCM4I&"; 39 mars_https::BYTE digest[20]; 40 mars_https::HMAC_SHA1((mars_https::BYTE*)strJoin.c_str(), strlen(strJoin.c_str()),(mars_https::BYTE*)strKey.c_str(),strlen(strKey.c_str()),digest); 41 int len = sizeof(digest); 42 string m_strSerialNumber=byteToHexStr(digest,len).c_str(); 43 cout<<m_strSerialNumber<<endl; 44 return 0; 45 }
Sha1.cpp
1 /* 2 100% free public domain implementation of the SHA-1 algorithm 3 by Dominik Reichl <dominik.reichl@t-online.de> 4 Web: http://www.dominik-reichl.de/ 5 6 Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) 7 - You can set the endianness in your files, no need to modify the 8 header file of the CSHA1 class any more 9 - Aligned data support 10 - Made support/compilation of the utility functions (ReportHash 11 and HashFile) optional (useful, if bytes count, for example in 12 embedded environments) 13 14 Version 1.5 - 2005-01-01 15 - 64-bit compiler compatibility added 16 - Made variable wiping optional (define SHA1_WIPE_VARIABLES) 17 - Removed unnecessary variable initializations 18 - ROL32 improvement for the Microsoft compiler (using _rotl) 19 20 ======== Test Vectors (from FIPS PUB 180-1) ======== 21 22 SHA1("abc") = 23 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 24 25 SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 26 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 27 28 SHA1(A million repetitions of "a") = 29 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 30 */ 31 32 #ifndef ___SHA1_HDR___ 33 #define ___SHA1_HDR___ 34 35 #if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) 36 #define SHA1_UTILITY_FUNCTIONS 37 #endif 38 39 #include <memory.h> // Needed for memset and memcpy 40 41 #ifdef SHA1_UTILITY_FUNCTIONS 42 #include <stdio.h> // Needed for file access and sprintf 43 #include <string.h> // Needed for strcat and strcpy 44 #endif 45 46 #ifdef _MSC_VER 47 #include <stdlib.h> 48 #endif 49 50 // You can define the endian mode in your files, without modifying the SHA1 51 // source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN 52 // in your files, before including the SHA1.h header file. If you don't 53 // define anything, the class defaults to little endian. 54 55 #if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) 56 #define SHA1_LITTLE_ENDIAN 57 #endif 58 59 // Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if 60 // not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it 61 // defaults to wiping. 62 63 #if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) 64 #define SHA1_WIPE_VARIABLES 65 #endif 66 67 ///////////////////////////////////////////////////////////////////////////// 68 // Define 8- and 32-bit variables 69 70 #ifndef UINT_32 71 72 #ifdef _MSC_VER 73 74 #define UINT_8 unsigned __int8 75 #define UINT_32 unsigned __int32 76 77 #else 78 79 #define UINT_8 unsigned char 80 81 #if (ULONG_MAX == 0xFFFFFFFF) 82 #define UINT_32 unsigned long 83 #else 84 #define UINT_32 unsigned int 85 #endif 86 87 #endif 88 #endif 89 90 ///////////////////////////////////////////////////////////////////////////// 91 // Declare SHA1 workspace 92 93 typedef union 94 { 95 UINT_8 c[64]; 96 UINT_32 l[16]; 97 } SHA1_WORKSPACE_BLOCK; 98 99 class CSHA1 100 { 101 public: 102 #ifdef SHA1_UTILITY_FUNCTIONS 103 // Two different formats for ReportHash(...) 104 enum 105 { 106 REPORT_HEX = 0, 107 REPORT_DIGIT = 1 108 }; 109 #endif 110 111 // Constructor and Destructor 112 CSHA1(); 113 ~CSHA1(); 114 115 UINT_32 m_state[5]; 116 UINT_32 m_count[2]; 117 UINT_32 __reserved1[1]; 118 UINT_8 m_buffer[64]; 119 UINT_8 m_digest[20]; 120 UINT_32 __reserved2[3]; 121 122 void Reset(); 123 124 // Update the hash value 125 void Update(UINT_8 *data, UINT_32 len); 126 #ifdef SHA1_UTILITY_FUNCTIONS 127 bool HashFile(char *szFileName); 128 #endif 129 130 // Finalize hash and report 131 void Final(); 132 133 // Report functions: as pre-formatted and raw data 134 #ifdef SHA1_UTILITY_FUNCTIONS 135 void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX); 136 #endif 137 void GetHash(UINT_8 *puDest); 138 139 private: 140 // Private SHA-1 transformation 141 void Transform(UINT_32 *state, UINT_8 *buffer); 142 143 // Member variables 144 UINT_8 m_workspace[64]; 145 SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above 146 }; 147 148 #endif
HmacSha1.cpp
HmacSha1.h
若有问题希望留言指正,感谢~