04.11.2004 23:17:37WinCrypt API в PocketPC 2003 Ответов: 2
AL-GALI
Проблема появиласть в PocketPC 2003 / 2003SE. Данный ниже код не дешифрует зашифрованные им же файлы. На WinXP, Win2000, PocketPC2002 все работает нормально. Кто-нибудь с этим сталкивался?
#ifndef __CRYPTDECRYPT_H__
#define __CRYPTDECRYPT_H__
//////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32_WCE
#define KEY_LENGTH_FLAG 0
#else
#define KEY_LENGTH_FLAG (dwKeyLength << 16)
class CEncryptDecryptException
{
public:
CEncryptDecryptException(unsigned int uiErrcode, const TCHAR *pccMessage)
{
pm_uiErrcode = uiErrcode;
pm_pccMessage = wcsdup(pccMessage);
}
CEncryptDecryptException(const TCHAR *pccMessage)
{
pm_uiErrcode = GetLastError();
pm_pccMessage = wcsdup(pccMessage);
}
~CEncryptDecryptException()
{
if (pm_pccMessage) free((void *)pm_pccMessage);
}
CEncryptDecryptException(const CEncryptDecryptException &e)
{
pm_uiErrcode = e.pm_uiErrcode;
pm_pccMessage = wcsdup(e.pm_pccMessage);
}
void ShowError()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
pm_uiErrcode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, pm_pccMessage, MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
private:
unsigned int pm_uiErrcode;
const TCHAR *pm_pccMessage;
};
#endif
//////////////////////////////////////////////////////////////////////////////
void ShowError(unsigned int uiErrCode, const TCHAR *ptcTitle);
//////////////////////////////////////////////////////////////////////////////
class CEncryptDecryptFile
{
public:
CEncryptDecryptFile();
#ifdef _WIN32_WCE
int Encrypt(const TCHAR *pccSource, const TCHAR *pccDestination,
const TCHAR *pccPassword);
#else
void Encrypt(const TCHAR *pccSource, const TCHAR *pccDestination,
const TCHAR *pccPassword);
#endif
#ifdef _WIN32_WCE
int Decrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword);
#else
void Decrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword);
#endif
unsigned int getErrCode() {return uiErrCode;}
private:
const TCHAR *pccErrMessage;
unsigned int uiErrCode;
FILE *hSrcFile, *hDestFile;
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey, hXchgKey;
#ifdef ARM
__unaligned PBYTE pbBuffer, pbKeyBlob;
#else
PBYTE pbBuffer, pbKeyBlob;
#endif
BOOL bEOF;
DWORD dwCount, dwKeyBlobLen, dwKeyLength;
CEncryptDecrypt(const CEncryptDecryptFile &);
BOOL pmSetKeyParams(HCRYPTKEY hKey);
void Init();
};
//////////////////////////////////////////////////////////////////////////////
#endif
//----------------------------------
#include "StdAfx.h"
#include "cryptdecrypt.h"
//////////////////////////////////////////////////////////////////////////////
#define BLOCK_SIZE 1000
#define BUFFER_SIZE (BLOCK_SIZE + 64)
//////////////////////////////////////////////////////////////////////////////
void ShowError(unsigned int uiErrCode, const TCHAR *ptcTitle)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
uiErrCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, ptcTitle, MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
//////////////////////////////////////////////////////////////////////////////
void CEncryptDecryptFile::Init()
{
hSrcFile = hDestFile = NULL;
hProv = 0;
hHash = 0;
hKey = hXchgKey = 0;
pbBuffer = pbKeyBlob = NULL;
bEOF = 0;
pccErrMessage = NULL;
uiErrCode = 0;
dwKeyLength = 40;
}
//////////////////////////////////////////////////////////////////////////////
CEncryptDecryptFile::CEncryptDecryptFile()
{
}
//////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32_WCE
int CEncryptDecryptFile::Encrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword)
#else
void CEncryptDecryptFile::Encrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword)
#endif
{
Init();
// Open the source file.
if ((hSrcFile = _wfopen (pccSource, L"rb")) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Open input file";
goto exit;
}
// Open the destination file.
if ((hDestFile = _wfopen (pccDestination, L"wb")) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Open output file";
goto exit;
}
// Get the handle to the default provider.
if (!CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
{
uiErrCode = GetLastError();
if (uiErrCode != NTE_BAD_KEYSET)
{
pccErrMessage = L"Error during CryptAcquireContext!";
goto exit;
}
else
{
if (!CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptAcquireContext!";
goto exit;
}
}
}
if (pccPassword == NULL)
{
// Encrypt the file with a random session key.
// Create a random session key.
if (!CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE | KEY_LENGTH_FLAG, &hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptGenKey!";
goto exit;
}
// Get the handle to the key exchange public key.
if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey))
{
uiErrCode = GetLastError();
if (uiErrCode != NTE_NO_KEY)
{
pccErrMessage = L"Error during CryptGetUserKey!";
goto exit;
}
// Create the key.
if (!CryptGenKey(hProv,AT_KEYEXCHANGE, KEY_LENGTH_FLAG, &hXchgKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptGenKey For KeyXchange!";
goto exit;
}
}
// Determine the size of the key BLOB and allocate memory.
if (!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL,
&dwKeyBlobLen))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error computing blob length!";
goto exit;
}
if ((pbKeyBlob = (PBYTE)malloc(dwKeyBlobLen))==NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Out of memory!";
goto exit;
}
// Export the session key into a simple key BLOB.
if (!CryptExportKey (hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob,
&dwKeyBlobLen))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptExportKey!";
goto exit;
}
// Write the size of key BLOB to the destination file.
fwrite (&dwKeyBlobLen, sizeof (DWORD), 1, hDestFile);
uiErrCode = GetLastError();
if (ferror (hDestFile))
{
pccErrMessage = L"Error writing header!";
goto exit;
}
// Write the key BLOB to the destination file.
fwrite (pbKeyBlob, 1, dwKeyBlobLen, hDestFile);
uiErrCode = GetLastError();
if (ferror (hDestFile))
{
pccErrMessage = L"Error writing header!";
goto exit;
}
}
else
{
// Encrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash (hProv, CALG_MD5, 0, 0, &hHash))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptCreateHash!";
goto exit;
}
// Hash in the password data.
if (!CryptHashData (hHash, (PBYTE)pccPassword,
wcslen(pccPassword) * sizeof(pccPassword[0]), 0))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptHashData!";
goto exit;
}
// Derive a session key from the hash object.
if (!CryptDeriveKey (hProv, CALG_RC2, hHash,
CRYPT_EXPORTABLE|KEY_LENGTH_FLAG|CRYPT_NO_SALT, &hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptDeriveKey!";
goto exit;
}
}
// Allocate memory.
// XXX: Changed: if ((pbBuffer=(PBYTE)malloc(dwKeyBlobLen))==NULL)
// C_ASSERT(BUFFER_SIZE > BLOCK_SIZE):
if ((pbBuffer=(PBYTE)malloc(BUFFER_SIZE)) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Out of memory!";
goto exit;
}
if (!pmSetKeyParams(hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during setting key parameters!";
goto exit;
}
// Encrypt the source file and write to the destination file.
do
{
// Read up to BLOCK_SIZE bytes from the source file.
dwCount = fread (pbBuffer, 1, BLOCK_SIZE, hSrcFile);
uiErrCode = GetLastError();
if (ferror (hSrcFile))
{
pccErrMessage = L"Error reading Plaintext!";
goto exit;
}
bEOF = (feof(hSrcFile) != 0);
// Encrypt the data.
if (!CryptEncrypt (hKey, 0, bEOF, 0, pbBuffer, &dwCount,
BUFFER_SIZE))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptEncrypt!";
goto exit;
}
// Write the data to the destination file.
fwrite (pbBuffer, 1, dwCount, hDestFile);
uiErrCode = GetLastError();
if (ferror (hDestFile))
{
pccErrMessage = L"Error writing Ciphertext!";
goto exit;
}
} while (!bEOF);
exit:
// Close the files.
if (hSrcFile) fclose (hSrcFile);
if (hDestFile) fclose (hDestFile);
// Free memory.
if (pbKeyBlob) free (pbKeyBlob);
if (pbBuffer) free (pbBuffer);
// Destroy the session key.
if (hKey) CryptDestroyKey (hKey);
// Release the key exchange key handle.
if (hXchgKey) CryptDestroyKey (hXchgKey);
// Destroy the hash object.
if (hHash) CryptDestroyHash (hHash);
// Release the provider handle.
if (hProv) CryptReleaseContext (hProv, 0);
if (pccErrMessage)
#ifdef _WIN32_WCE
return -1;
else
return 0;
#else
throw CEncryptDecryptException(uiErrCode,pccErrMessage);
#endif
}
//////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32_WCE
int CEncryptDecryptFile::Decrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword)
#else
void CEncryptDecryptFile::Decrypt(const TCHAR *pccSource,
const TCHAR *pccDestination,
const TCHAR *pccPassword)
#endif
{
Init();
// Open the source file.
if ((hSrcFile = _wfopen (pccSource, L"rb")) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Error opening Ciphertext file!";
goto exit;
}
// Open the destination file.
if ((hDestFile = _wfopen (pccDestination, L"wb")) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Error opening Plaintext file!";
goto exit;
}
// Get the handle to the default provider.
if (!CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_FULL, 0))
{
uiErrCode = GetLastError();
if (uiErrCode != NTE_BAD_KEYSET)
{
pccErrMessage = L"Error during CryptAcquireContext!";
goto exit;
}
else
{
if (!CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptAcquireContext!";
goto exit;
}
}
}
if (pccPassword == NULL)
{
// Decrypt the file with the saved session key.
// Read key BLOB length from the source file and allocate memory.
fread (&dwKeyBlobLen, sizeof (DWORD), 1, hSrcFile);
uiErrCode = GetLastError();
if (ferror (hSrcFile) || feof (hSrcFile))
{
pccErrMessage = L"Error reading file header!";
goto exit;
}
if ((pbKeyBlob = (PBYTE)malloc (dwKeyBlobLen)) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Out of memory or improperly formatted source";
goto exit;
}
// Read the key BLOB from source file.
fread (pbKeyBlob, 1, dwKeyBlobLen, hSrcFile);
uiErrCode = GetLastError();
if (ferror (hSrcFile) || feof (hSrcFile))
{
pccErrMessage = L"Error reading file header!";
goto exit;
}
// Import the key BLOB into the CSP.
if (!CryptImportKey(hProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptImportKey!";
goto exit;
}
}
else
{
// Decrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash (hProv, CALG_MD5, 0, 0, &hHash))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptCreateHash!";
goto exit;
}
// Hash in the password data.
if (!CryptHashData (hHash, (PBYTE)pccPassword,
wcslen(pccPassword) * sizeof(pccPassword[0]), 0))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptHashData!";
goto exit;
}
// Derive a session key from the hash object.
if (!CryptDeriveKey (hProv, CALG_RC2, hHash, KEY_LENGTH_FLAG|CRYPT_NO_SALT, &hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptDeriveKey!";
goto exit;
}
}
if (!pmSetKeyParams(hKey))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during setting key parameters!";
goto exit;
}
// Allocate memory.
if ((pbBuffer = (PBYTE)malloc (BUFFER_SIZE)) == NULL)
{
uiErrCode = GetLastError();
pccErrMessage = L"Out of memory!";
goto exit;
}
// Decrypt the source file and write to the destination file.
do
{
// Read up to BLOCK_SIZE bytes from the source file.
dwCount = fread(pbBuffer, 1, BLOCK_SIZE, hSrcFile);
uiErrCode = GetLastError();
if (ferror(hSrcFile))
{
pccErrMessage = L"Error reading Ciphertext!";
goto exit;
}
bEOF = (feof(hSrcFile) != 0);
// Decrypt the data.
if (!CryptDecrypt (hKey, 0, bEOF, 0, pbBuffer, &dwCount))
{
uiErrCode = GetLastError();
pccErrMessage = L"Error during CryptDecrypt!";
goto exit;
}
// Write the data to the destination file.
fwrite (pbBuffer, 1, dwCount, hDestFile);
uiErrCode = GetLastError();
if (ferror(hDestFile))
{
pccErrMessage = L"Error writing Plaintext!";
goto exit;
}
} while (!bEOF);
exit:
// Close the source files.
if (hSrcFile) fclose (hSrcFile);
if (hDestFile) fclose (hDestFile);
// Free memory.
if (pbKeyBlob) free (pbKeyBlob);
if (pbBuffer) free (pbBuffer);
// Destroy the session key.
if (hKey) CryptDestroyKey (hKey);
// Destroy the hash object.
if (hHash) CryptDestroyHash (hHash);
// Release the provider handle.
if (hProv) CryptReleaseContext (hProv, 0);
if (pccErrMessage)
#ifdef _WIN32_WCE
return -1;
else
return 0;
#else
throw CEncryptDecryptException(uiErrCode,pccErrMessage);
#endif
}
//////////////////////////////////////////////////////////////////////////////
BOOL CEncryptDecryptFile::pmSetKeyParams(HCRYPTKEY hKey)
{
if (!CryptSetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (BYTE *)&dwKeyLength, 0))
return FALSE;
return TRUE;
}
 
Ответы:
05.11.2004 10:20:42Kirill Sobolev
Вообще-то разбираться в отличии работы на разных платформах 14кб чужого кода не самая легкая (и не самая интересная) задача... Мб Вы предоставите более подробную информацию - что именно не работает, код ошибки и т.д.?
05.11.2004 15:25:49AL-GALI
Уже нашел ошибку. Прошу не беспокоиться :)