TWinCryptF.cpp 5.2 KB

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