/* blowfish类 by dzj, 09.08.25 */ #include #include #ifdef CLI_DLL_ENC #include "EncryptSendPkg.h" #endif //CLI_DLL_ENC #ifdef CHECK_ENDIAN #define ENDIAN_CHANGE_S( toTran ) ((toTran<<8) | (toTran>>8)) #define ENDIAN_CHANGE_L( toTran ) ((toTran<<24) | (toTran>>8<<24>>8) | (toTran<<8>>24<<8) | (toTran>>24)) extern bool g_isBigEndian; #endif //CHECK_ENDIAN #ifdef CLI_DLL_ENC #define _founc(x,y) y##_##x##_code #define _founc_len(x,y) y##_##x##_code_LEN #endif //CLI_DLL_ENC //using namespace std; // //#ifdef MY_WIN32 // class MySelfFunc // { // //bool ProcRandomStrEnc() // //{ // // //} // static bool ProcRandomStrNoEnc( HMODULE (*__GetModuleHandle)( LPCTSTR lpModuleName ) // , void (*__build_md5)(const std::string & id, const std::string & passwrd, const char * randomString, int randomStringlen, char * dst), // , int tmplen, char* tmpin, const char* account, int rstrlen, const char* rstr, char* md5val ) // { // if ( tmplen >= 1 ) // { // DWORD thisseed = (DWORD) __GetModuleHandle( NULL ); // for ( int i=0; i>i) ); // tmpin[i] -= cipher; // } // } // // __build_md5( account, tmpin, rstr, rstrlen, md5val );//计算md5值; // return true; // } // // static void ProcPassword( HMODULE (*__GetModuleHandle)( LPCTSTR lpModuleName ) // , int tmplen, char* tmpin, const char* inPassword ) // { // if ( tmplen >= 1 ) // { // DWORD thisseed = (DWORD) __GetModuleHandle( NULL ); // for ( int i=0; i>i) ); // tmpin[i] = (cipher + inPassword[i]); // } // } // return; // } // }; ////#endif MY_WIN32 ///blowfish类; class DsCryptBF { public: DsCryptBF() { #ifdef CLI_DLL_ENC m_pfnBFEnc = NULL; m_pfnBFDec = NULL; #endif //CLI_DLL_ENC InitCryptBF(); }; ~DsCryptBF() { #ifdef CLI_DLL_ENC if ( NULL != m_pfnBFDec ) { delete [] m_pfnBFDec; m_pfnBFDec = NULL; } if ( NULL != m_pfnBFEnc ) { delete [] m_pfnBFEnc; m_pfnBFEnc = NULL; } #endif //CLI_DLL_ENC }; public: #ifndef CLI_DLL_ENC #ifdef MY_WIN32 ///加密待发送包,待发送包的前sizeof(unsigned int)个字节必须要空出,等待此处填写包序号, outLen = inLen+sizeof(unsigned short); static bool __EncryptSendPkg( void* (__cdecl *_memcpy)(void *dest,const void *src,size_t count) , void (*__BF_cfb64_encrypt)(const unsigned char *in, unsigned char *out, long length, const BF_KEY *schedule, unsigned char *ivec, int *num, int enc) #ifdef CHECK_ENDIAN , bool isBigEndian #endif //CHECK_ENDIAN , bool isStSendCrypt, unsigned int& sendPkgID, BF_KEY& schsend, unsigned char ivecsend[8], int& numsend , const unsigned char* inPkg/*待填写的包序号+真正待加密的包内容*/, unsigned int inLen , unsigned char* outBuf, unsigned int outBufLen, unsigned int& outPkgLen, unsigned int timeInfo=0, bool isAddTime=false/*是否在包中添加时间信息*/ ) { if ( !isAddTime ) { //无附加时间信息 if ( inLen <= sizeof(unsigned int)/*包序号*/ ) { //输入数据有误; return false; } } else { //有附加时间信息 if ( inLen <= sizeof(unsigned int)/*时间信息*/+sizeof(unsigned int)/*包序号*/ ) { //输入数据有误; return false; } } if ( isStSendCrypt ) { //加密:输出包结构:加密包长度|(包序号+真正待加密包内容)加密结果; outPkgLen = inLen/*有效数据的长度+sizeof(unsigned int包序号)+sizeof(unsigned int可能的时间信息)*/ + sizeof(unsigned short)/*加密包长度字度的长度*/; *((unsigned short*) outBuf) = outPkgLen; #ifdef CHECK_ENDIAN if ( isBigEndian ) { *((unsigned short*) outBuf) = ENDIAN_CHANGE_S(outPkgLen); } #endif //CHECK_ENDIAN if ( outPkgLen > outBufLen ) { return false;//输出缓存不够; } ++sendPkgID; if ( isAddTime ) { *((unsigned int*) inPkg) = timeInfo;//附加的时间信息; *((unsigned int*)(inPkg+sizeof(unsigned int))) = sendPkgID;//填写发送包序号,这一序号也会被加密; } else { *((unsigned int*) inPkg) = sendPkgID;//填写发送包序号,这一序号也会被加密; } #ifdef CHECK_ENDIAN if ( isBigEndian ) { if ( isAddTime ) { *((unsigned int*) inPkg) = ENDIAN_CHANGE_L(timeInfo);//附加的时间信息; *((unsigned int*)(inPkg+sizeof(unsigned int))) = ENDIAN_CHANGE_L(sendPkgID);//填写发送包序号,这一序号也会被加密; } else { *((unsigned int*) inPkg) = ENDIAN_CHANGE_L(sendPkgID);//填写发送包序号,这一序号也会被加密; } } #endif //CHECK_ENDIAN __BF_cfb64_encrypt( inPkg, outBuf+sizeof(unsigned short), inLen, &schsend, ivecsend, &numsend, BF_ENCRYPT ); } else { //明文:输出包结构:去除前sizeof(unsigned int)个字节的原inPkg; if ( !isAddTime ) { //无附加时间信息; outPkgLen = inLen - sizeof(unsigned int)/*除去包序号字段的长度*/; } else { outPkgLen = inLen - sizeof(unsigned int)/*除去包序号字段的长度*/ - sizeof(unsigned int)/*除去时间信息字段的长度*/; } if ( outPkgLen > outBufLen ) { return false;//输出缓存不够; } if ( !isAddTime ) { _memcpy( outBuf, inPkg+sizeof(unsigned int), inLen - sizeof(unsigned int) ); } else { _memcpy( outBuf, inPkg+sizeof(unsigned int)+sizeof(unsigned int), inLen - sizeof(unsigned int)-sizeof(unsigned int) ); } } return true; } static int __EncryptEnd() { return 0; } ///解密接收包,输入不包含明文形式密文长度的整个密文(包长度--已去除+可能的时间信息+包序号+包长度+包类型+命令字+包内容),输出:明文(包类型+命令字+包内容); static bool __DecryptRcvPkg( void* (__cdecl *_memcpy)(void *dest,const void *src,size_t count) , void (*__BF_cfb64_encrypt)(const unsigned char *in, unsigned char *out, long length, const BF_KEY *schedule, unsigned char *ivec, int *num, int enc) #ifdef CHECK_ENDIAN , bool isBigEndian #endif //CHECK_ENDIAN , bool isStRcvCrypt, unsigned int& rcvPkgID, BF_KEY& schrcv, unsigned char ivecrcv[8], int& numrcv , const unsigned char* inPkg, unsigned int inLen, unsigned char* outBuf, unsigned int outBufLen , unsigned char*& outPkg/*输出包起始位置,outBuf+x*/, unsigned int& outPkgLen, unsigned int& timeInfo, bool isWithTime=false ) { timeInfo = 0; if ( ( NULL == inPkg ) || ( inLen <= 0 ) ) { //printf( "解密错1", m_rcvPkgID, (*(unsigned int*) outBuf) ); return false; } if ( isStRcvCrypt ) { if ( isWithTime ) { //包含时间信息收包; if ( inLen <= sizeof(unsigned int)/*时间信息字段*/ + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ) { //printf( "解密错2" ); return false; } outPkgLen = inLen - ( sizeof(unsigned int)/*时间信息字段*/ + sizeof(int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ); } else { //无时间信息收包; if ( inLen <= sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ) { //printf( "解密错2" ); return false; } outPkgLen = inLen - (sizeof(int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/); } if ( outPkgLen > outBufLen ) { //printf( "解密错3" ); return false;//输出缓存不够; } //输入包结构:加密包长度|(包序号+真正待加密信息)加密结果,输出包:已加密信息-包序号-明文包长度; __BF_cfb64_encrypt( inPkg, outBuf, inLen, &schrcv, ivecrcv, &numrcv, BF_DECRYPT ); ++rcvPkgID;//接收包序号,这一序号也会被加密; unsigned int decedPkgID = 0;//解出的包序号,与m_rcvPkgID作对比; if ( isWithTime ) { //带时间信息; timeInfo = *((unsigned int*)outBuf); decedPkgID = *((unsigned int*)(outBuf+sizeof(unsigned int))); } else { decedPkgID = *((unsigned int*)outBuf); } #ifdef CHECK_ENDIAN if ( isBigEndian ) { if ( isWithTime ) { //带时间信息; timeInfo = ENDIAN_CHANGE_L(*((unsigned int*)outBuf)); decedPkgID = ENDIAN_CHANGE_L(*((unsigned int*)(outBuf+sizeof(unsigned int)))); } else { decedPkgID = ENDIAN_CHANGE_L(*((unsigned int*)outBuf)); } } #endif //CHECK_ENDIAN if ( rcvPkgID != decedPkgID ) { //printf( "解密序号出错:%d,%d\n", m_rcvPkgID, (*(unsigned int*) outBuf) ); return false; } if ( isWithTime ) { outPkg = outBuf + sizeof(unsigned int)/*加密的时间信息*/ + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/; } else { outPkg = outBuf + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/; } } else { //输入为明文,原样输出; outPkgLen = inLen; if ( outPkgLen > outBufLen ) { return false;//输出缓存不够; } //输入包结构:去除包长度的明文(包类型+命令字+包内容); _memcpy( outBuf, inPkg, inLen ); outPkg = outBuf; } return true; } static int __DecryptEnd() { return 0; } #endif MY_WIN32 #endif //#ifndef CLI_DLL_ENC public: void InitCryptBF() { #ifdef CLI_DLL_ENC LoadPFnBFEnc(); LoadPFnBFDec(); #endif //CLI_DLL_ENC m_isSendKeySet = false; m_isRcvKeySet = false; m_isStSendCrypt = false;//是否启用发送加密; m_isStRcvCrypt = false;//是否启用接收加密; for ( int i=0; i<8; ++i ) { m_ivecsend[i] = m_ivecrcv[i] = i; //rand()%256; } m_numsend = 0; m_numrcv = 0; m_sendPkgID = 0;//发送包序号,第一个包为1; m_rcvPkgID = 0;//接收包序号,第一个包为1; return; } private: #ifdef CLI_DLL_ENC void LoadPFnBFEnc() { int code_len=EncryptSendPkg_CODE_LEN; m_pfnBFEnc = new unsigned char[code_len+1]; memset( m_pfnBFEnc, 0, sizeof(unsigned char)*(code_len+1) ); unsigned char* pcode=(unsigned char*)malloc(code_len*sizeof(unsigned char)); if (pcode == NULL) { return; } int p; int hp=0; for (int k=1;k<=EncryptSendPkg_ARRAY_NUM;k++) { switch(k) { case 1: for (p=0;p<_founc_len(00001,EncryptSendPkg);p++) { pcode[hp+p]=_founc(00001,EncryptSendPkg)[p]; } hp=hp+p; break; case 2: for (p=0;p<_founc_len(00002,EncryptSendPkg);p++) { pcode[hp+p]=_founc(00002,EncryptSendPkg)[p]; } hp=hp+p; break; case 3: for (p=0;p<_founc_len(00003,EncryptSendPkg);p++) { pcode[hp+p]=_founc(00003,EncryptSendPkg)[p]; } hp=hp+p; break; case 4: for (p=0;p<_founc_len(00004,EncryptSendPkg);p++) { pcode[hp+p]=_founc(00004,EncryptSendPkg)[p]; } hp=hp+p; break; default: break; } } for (int i=0;i outBufLen ) { return false;//输出缓存不够; } ++m_sendPkgID; if ( isAddTime ) { *((unsigned int*) inPkg) = timeInfo;//附加的时间信息; *((unsigned int*)(inPkg+sizeof(unsigned int))) = m_sendPkgID;//填写发送包序号,这一序号也会被加密; } else { *((unsigned int*) inPkg) = m_sendPkgID;//填写发送包序号,这一序号也会被加密; } #ifdef CHECK_ENDIAN if ( g_isBigEndian ) { if ( isAddTime ) { *((unsigned int*) inPkg) = ENDIAN_CHANGE_L(timeInfo);//附加的时间信息; *((unsigned int*)(inPkg+sizeof(unsigned int))) = ENDIAN_CHANGE_L(m_sendPkgID);//填写发送包序号,这一序号也会被加密; } else { *((unsigned int*) inPkg) = ENDIAN_CHANGE_L(m_sendPkgID);//填写发送包序号,这一序号也会被加密; } } #endif //CHECK_ENDIAN BF_cfb64_encrypt( inPkg, outBuf+sizeof(unsigned short), inLen, &m_schsend, m_ivecsend, &m_numsend, BF_ENCRYPT ); } else { //明文:输出包结构:去除前sizeof(unsigned int)个字节的原inPkg; if ( !isAddTime ) { //无附加时间信息; outPkgLen = inLen - sizeof(unsigned int)/*除去包序号字段的长度*/; } else { outPkgLen = inLen - sizeof(unsigned int)/*除去包序号字段的长度*/ - sizeof(unsigned int)/*除去时间信息字段的长度*/; } if ( outPkgLen > outBufLen ) { return false;//输出缓存不够; } if ( !isAddTime ) { memcpy( outBuf, inPkg+sizeof(unsigned int), inLen - sizeof(unsigned int) ); } else { memcpy( outBuf, inPkg+sizeof(unsigned int)+sizeof(unsigned int), inLen - sizeof(unsigned int)-sizeof(unsigned int) ); } } return true; } #endif //CLI_DLL_ENC ///解密接收包,输入不包含明文形式密文长度的整个密文(包长度--已去除+可能的时间信息+包序号+包长度+包类型+命令字+包内容),输出:明文(包类型+命令字+包内容); bool DecryptRcvPkg( const unsigned char* inPkg, unsigned int inLen, unsigned char* outBuf, unsigned int outBufLen , unsigned char*& outPkg/*输出包起始位置,outBuf+x*/, unsigned int& outPkgLen, unsigned int& timeInfo, bool isWithTime=false ) #ifdef CLI_DLL_ENC { return ((PFnMyBFDec)m_pfnBFDec)( memcpy, BF_cfb64_encrypt #ifdef CHECK_ENDIAN , g_isBigEndian #endif //CHECK_ENDIAN , m_isStRcvCrypt, m_rcvPkgID, m_schrcv, m_ivecrcv, m_numrcv, inPkg , inLen, outBuf, outBufLen, outPkg, outPkgLen, timeInfo, isWithTime ); } #else //CLI_DLL_ENC { timeInfo = 0; if ( ( NULL == inPkg ) || ( inLen <= 0 ) ) { //printf( "解密错1", m_rcvPkgID, (*(unsigned int*) outBuf) ); return false; } if ( m_isStRcvCrypt ) { if ( isWithTime ) { //包含时间信息收包; if ( inLen <= sizeof(unsigned int)/*时间信息字段*/ + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ) { //printf( "解密错2" ); return false; } outPkgLen = inLen - ( sizeof(unsigned int)/*时间信息字段*/ + sizeof(int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ); } else { //无时间信息收包; if ( inLen <= sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/ ) { //printf( "解密错2" ); return false; } outPkgLen = inLen - (sizeof(int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/); } if ( outPkgLen > outBufLen ) { //printf( "解密错3" ); return false;//输出缓存不够; } //输入包结构:加密包长度|(包序号+真正待加密信息)加密结果,输出包:已加密信息-包序号-明文包长度; BF_cfb64_encrypt( inPkg, outBuf, inLen, &m_schrcv, m_ivecrcv, &m_numrcv, BF_DECRYPT ); ++m_rcvPkgID;//接收包序号,这一序号也会被加密; unsigned int decedPkgID = 0;//解出的包序号,与m_rcvPkgID作对比; if ( isWithTime ) { //带时间信息; timeInfo = *((unsigned int*)outBuf); decedPkgID = *((unsigned int*)(outBuf+sizeof(unsigned int))); } else { decedPkgID = *((unsigned int*)outBuf); } #ifdef CHECK_ENDIAN if ( g_isBigEndian ) { if ( isWithTime ) { //带时间信息; timeInfo = ENDIAN_CHANGE_L(*((unsigned int*)outBuf)); decedPkgID = ENDIAN_CHANGE_L(*((unsigned int*)(outBuf+sizeof(unsigned int)))); } else { decedPkgID = ENDIAN_CHANGE_L(*((unsigned int*)outBuf)); } } #endif //CHECK_ENDIAN if ( m_rcvPkgID != decedPkgID ) { //printf( "解密序号出错:%d,%d\n", m_rcvPkgID, (*(unsigned int*) outBuf) ); return false; } if ( isWithTime ) { outPkg = outBuf + sizeof(unsigned int)/*加密的时间信息*/ + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/; } else { outPkg = outBuf + sizeof(unsigned int)/*加密序号字段*/ + sizeof(short)/*加密的明文长度字段*/; } } else { //输入为明文,原样输出; outPkgLen = inLen; if ( outPkgLen > outBufLen ) { return false;//输出缓存不够; } //输入包结构:去除包长度的明文(包类型+命令字+包内容); memcpy( outBuf, inPkg, inLen ); outPkg = outBuf; } return true; } #endif //CLI_DLL_ENC private: bool m_isSendKeySet;//是否已设发送密钥 bool m_isRcvKeySet;//是否已设接收密钥 bool m_isStSendCrypt;//是否启用发送加密; bool m_isStRcvCrypt;//是否启用接收加密; BF_KEY m_schsend;//发送密钥 BF_KEY m_schrcv;//接收密钥 unsigned char m_ivecsend[8];//发送用ivec; unsigned char m_ivecrcv[8];//接收用ivec int m_numsend;//发送用num int m_numrcv;//接收用num unsigned int m_sendPkgID;//发送包序号,第一个包为1; unsigned int m_rcvPkgID;//接收包序号,第一个包为1; #ifdef CLI_DLL_ENC typedef bool (*PFnMyBFEnc)( void* (__cdecl *_memcpy)(void *dest,const void *src,size_t count) , void (*__BF_cfb64_encrypt)(const unsigned char *in, unsigned char *out, long length, const BF_KEY *schedule, unsigned char *ivec, int *num, int enc) #ifdef CHECK_ENDIAN , bool isBigEndian #endif //CHECK_ENDIAN , bool isStSendCrypt, unsigned int& sendPkgID, BF_KEY& schsend, unsigned char ivecsend[8], int& numsend , const unsigned char* inPkg/*待填写的包序号+真正待加密的包内容*/, unsigned int inLen , unsigned char* outBuf, unsigned int outBufLen, unsigned int& outPkgLen, unsigned int timeInfo, bool isAddTime/*是否在包中添加时间信息*/ ); typedef bool (*PFnMyBFDec)( void* (__cdecl *_memcpy)(void *dest,const void *src,size_t count) , void (*__BF_cfb64_encrypt)(const unsigned char *in, unsigned char *out, long length, const BF_KEY *schedule, unsigned char *ivec, int *num, int enc) #ifdef CHECK_ENDIAN , bool isBigEndian #endif //CHECK_ENDIAN , bool isStRcvCrypt, unsigned int& rcvPkgID, BF_KEY& schrcv, unsigned char ivecrcv[8], int& numrcv , const unsigned char* inPkg, unsigned int inLen, unsigned char* outBuf, unsigned int outBufLen , unsigned char*& outPkg/*输出包起始位置,outBuf+x*/, unsigned int& outPkgLen, unsigned int& timeInfo, bool isWithTime ); unsigned char* m_pfnBFEnc;//加密函数; unsigned char* m_pfnBFDec;//解密函数; #endif //CLI_DLL_ENC };