TWinCryptF.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //---------------------------------------------------------------------------
  2. #include "pch.h"
  3. #include "TWinCryptF.h"
  4. //---------------------------------------------------------------------------
  5. #pragma package(smart_init)
  6. TWinCrypt::TWinCrypt()
  7. {
  8. FProv = FHash = FKey = 0;
  9. //FDefaultKeyRaw = "fdC)Y%yum3ww09";
  10. FDefaultKeyRaw = (char*)"HfdC)A%yum3Nw09";
  11. }
  12. //---------------------------------------------------------------------------
  13. TWinCrypt::~TWinCrypt()
  14. {
  15. if (FKey) CryptDestroyKey(FKey);
  16. if (FHash) CryptDestroyHash(FHash);
  17. if (FProv) CryptReleaseContext(FProv, 0);
  18. FProv = FHash = FKey = 0;
  19. }
  20. //---------------------------------------------------------------------------
  21. bool TWinCrypt::SetKey(LPCSTR szKey, LPCSTR szSalt/*=NULL*/)
  22. {
  23. FOk = true;
  24. if (!FProv)
  25. {
  26. FOk = CryptAcquireContext(&FProv,
  27. NULL,
  28. MS_DEF_PROV,
  29. PROV_RSA_FULL,
  30. CRYPT_VERIFYCONTEXT
  31. );
  32. }
  33. if (FOk && (0 != FHash))
  34. {
  35. FOk = CryptDestroyHash(FHash);
  36. FHash = NULL;
  37. }
  38. if (FOk && (!FHash))
  39. {
  40. FOk = CryptCreateHash(FProv, CALG_MD5, 0, 0, &FHash);
  41. }
  42. if (FOk)
  43. {
  44. if (!szKey)
  45. {
  46. // request to use default rawKey
  47. char szTmp[100];
  48. strcpy_s( szTmp, sizeof(szTmp), FDefaultKeyRaw);
  49. if (szSalt)
  50. {
  51. strncat_s(szTmp, sizeof(szTmp), szSalt, 5); // use part of salt
  52. }
  53. // minor security tweak -- scramble the key+salt
  54. int nLen= strlen(szTmp)-1;
  55. for (int j = 0; j < nLen; j++)
  56. {
  57. char c = szTmp[nLen-j];
  58. szTmp[nLen-j] = (char)(szTmp[j]+5);
  59. szTmp[j]= c;
  60. }
  61. szKey = &szTmp[4]; // discard the first part, for fun
  62. }
  63. FOk = CryptHashData(FHash, (BYTE*)szKey, strlen(szKey), 0);
  64. }
  65. if (FOk)
  66. {
  67. FOk = CryptDeriveKey(FProv, CALG_RC4, FHash, CRYPT_EXPORTABLE, &FKey);
  68. }
  69. if (!FOk)
  70. {
  71. FLastErr= GetLastError();
  72. FErrMsg= "Error creating encryption key";
  73. }
  74. return FOk;
  75. }
  76. //---------------------------------------------------------------------------
  77. bool TWinCrypt::EncryptDecrypt(BYTE* pData, DWORD* dwDataLen, LPCSTR pKey, bool fEncrypt)
  78. {
  79. FOk = true;
  80. SetKey((LPCSTR)pKey);
  81. if (fEncrypt)
  82. {
  83. FOk = CryptEncrypt(FKey, 0, true, 0, pData, dwDataLen, *dwDataLen);
  84. }
  85. else
  86. {
  87. FOk = CryptDecrypt(FKey, 0, true, 0, pData, dwDataLen);
  88. }
  89. return FOk;
  90. }
  91. //---------------------------------------------------------------------------
  92. std::string TWinCrypt::EncryptStrToHex(LPCSTR szText, LPCSTR pszKey/* = 0*/, LPCSTR pszSalt/* = 0*/)
  93. {
  94. FOk = true;
  95. std::string sRet= "";
  96. DWORD nDataLen = strlen(szText);
  97. if (pszSalt || pszKey || (NULL == FKey))
  98. {
  99. FOk = SetKey((LPCSTR)pszKey, pszSalt);
  100. }
  101. if (FOk)
  102. {
  103. char* pTmp = new char[nDataLen+1] ;
  104. strncpy_s(pTmp, nDataLen+1, szText, nDataLen+1);
  105. FOk = CryptEncrypt(FKey, 0, TRUE, 0, (BYTE*)pTmp, &nDataLen, nDataLen);
  106. if (FOk ) {
  107. sRet = EncodeToHex( (BYTE*)pTmp, nDataLen );
  108. }
  109. delete pTmp;
  110. }
  111. return sRet;
  112. }
  113. //---------------------------------------------------------------------------
  114. // inefficient but requires no explanation :-)
  115. std::string TWinCrypt::EncodeToHex(BYTE* p, int nLen)
  116. {
  117. std::string sRet;
  118. sRet = "";
  119. for(int j = 0; j < nLen; j++)
  120. {
  121. char hexChars[3];
  122. snprintf(hexChars, sizeof(hexChars), "%02X", p[j]);
  123. sRet += hexChars;
  124. }
  125. return sRet;
  126. }
  127. //---------------------------------------------------------------------------
  128. std::string TWinCrypt::DecryptStrFromHex(LPCSTR szHex, LPCSTR pszKey/* = 0*/, LPCSTR pszSalt/* = 0*/)
  129. {
  130. FOk = TRUE;
  131. std::string sRet= "";
  132. DWORD nDataLen= strlen(szHex);
  133. if (pszSalt || pszKey || (0 == FKey))
  134. {
  135. FOk = SetKey((LPCSTR)pszKey, pszSalt);
  136. }
  137. if (FOk)
  138. {
  139. DWORD nDecryptLen = nDataLen/2;
  140. char* pTmp = new char[nDecryptLen+1];
  141. DecodeFromHex(szHex, (BYTE*)pTmp, nDecryptLen);
  142. FOk = CryptDecrypt(FKey, 0, true, 0, (BYTE*)pTmp, &nDecryptLen );
  143. if (FOk)
  144. {
  145. sRet= pTmp;
  146. }
  147. delete pTmp;
  148. }
  149. return sRet;
  150. }
  151. //---------------------------------------------------------------------------
  152. // returns length of decoded hex buffer
  153. int TWinCrypt::DecodeFromHex(LPCSTR pSrc, BYTE* pDest, int nBufLen)
  154. {
  155. int nRet = 0;
  156. int nLen = strlen(pSrc);
  157. *pDest = 0;
  158. BYTE cIn1, cIn2, nFinal;
  159. for( int j=0; j< nLen; j += 2 )
  160. {
  161. cIn1= (BYTE)toupper(*pSrc++); cIn1 -= '0'; if ( cIn1>9 ) cIn1 -= 7;
  162. cIn2= (BYTE)toupper(*pSrc++); cIn2 -= '0'; if ( cIn2>9 ) cIn2 -= 7;
  163. nFinal= (BYTE)((cIn1 << 4) | cIn2);
  164. if (nFinal>255) nFinal=0; // in case trying to decode non-hex data
  165. *pDest++ = nFinal;
  166. *pDest = 0;
  167. if ( nRet >= nBufLen )
  168. {
  169. break;
  170. }
  171. nRet++;
  172. }
  173. return nRet;
  174. }
  175. //---------------------------------------------------------------------------