Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

решения / wincrypto

.cpp
Скачиваний:
3
Добавлен:
18.02.2023
Размер:
6.45 Кб
Скачать
// wincrypto.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
// 1. Создать тестовое, виды: приложение которое шифрует и дешифрует содержимое любого файла, алгоритмом DES; 
// 2. Организовать асоциированную карту строк, с возможностью быстрого поиска по хеш-таблице MD2;

#include <iostream>
#include <Windows.h>

#define KEYLENGTH  0x00800000 // 128-бит
#define ENCRYPT_ALGORITHM CALG_DES 
#define ENCRYPT_BLOCK_SIZE 8 

HANDLE hSourceFile = INVALID_HANDLE_VALUE;
HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
PBYTE Buffer = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTPROV hProv = NULL;

int FreeData();

using namespace std;

int wmain(int argc, wchar_t* argv[])
{
    setlocale(LC_ALL, "Russian");
    if (argc < 3)
    {
        cout << "wincrypto.exe [имя файла] [пароль] [шифрование (1)/дешифрование (0)]" << endl;
        return 0;
    }
    TCHAR Source[] = TEXT("crypt.tmp");
    LPTSTR Destination = argv[1];
    LPTSTR Password = argv[2];
    BOOL Direction;

    if(!wcscmp(argv[3], TEXT("1"))) Direction = TRUE;
    else if (!wcscmp(argv[3], TEXT("0"))) Direction = FALSE;
    else
    {
        cout << "wincrypto.exe [имя файла] [пароль] [1 или 0]" << endl;
        return 0;
    }

    DWORD BlockLen;
    DWORD BufferLen;
    DWORD Count;

    if (!MoveFile(Destination, Source))
    {
        cout << "Ошибка работы с указанным файлом!" << endl;
        return 0;
    }
    // открываем файл для чтения 
    hSourceFile = CreateFile(Source, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hSourceFile)
    {
        cout << "Ошибка открытия файла для чтения!" << endl;
        return FreeData();
    }
    
    // Открываем файл для записи
    hDestinationFile = CreateFile(Destination, FILE_WRITE_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hDestinationFile)
    {
        cout << "Ошибка открытия файла для записи!" << endl;
        return FreeData();
    }

    // получаем провайдер
    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) // MS_ENHANCED_PROV
    {
        cout << "Ошибка при выполнении CryptAcquireContext!" << endl;
        return FreeData();
    }

    // файл будет зашифрован хешом ключа
    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
    {
        cout << "Ошибка при выполнении CryptCreateHash!" << endl;
        return FreeData();
    }

    // получаем хеш пароля
    if (!CryptHashData(hHash, (BYTE*)Password, lstrlen(Password), 0))
    {
        cout << "Ошибка при выполнении CryptHashData!" << endl;
        return FreeData();
    }

    // получаем сессионный ключ из хеша пароля 
    if (!CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey))
    {
        cout << "Ошибка при выполнении CryptDeriveKey!" << endl;
        return FreeData();
    }

    // определяем количество байт для шифрования за раз
    BlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

    // определяем размер буфера
    if (ENCRYPT_BLOCK_SIZE > 1) BufferLen = BlockLen + ENCRYPT_BLOCK_SIZE;
    else BufferLen = BlockLen;

    BYTE* Buffer = new BYTE[BufferLen];

    // читаем, шифруем, записываем пока не закончится файл
    bool fEOF = FALSE;
    do
    {
        // чтение данных
        if (!ReadFile(hSourceFile, Buffer, BlockLen, &Count, NULL))
        {
            cout << "Ошибка чтения текста из файла!" << endl;
            return FreeData();
        }

        if (Count < BlockLen) fEOF = TRUE;
        
        if (Direction)
        {
            // шифрование
            if (!CryptEncrypt(hKey, NULL, fEOF, 0, Buffer, &Count, BufferLen))
            {
                cout << "Ошибка при выполнении CryptEncrypt!" << endl;
                return FreeData();
            }
        }
        else
        {
            // дешифрование
            if (!CryptDecrypt(hKey, NULL, fEOF, 0, Buffer, &Count))
            {
                cout << "Ошибка при выполнении CryptDecrypt!" << endl;
                return FreeData();
            }
        }

        // запись шифр в файл 
        if (!WriteFile(hDestinationFile, Buffer, Count, &Count, NULL))
        {
            cout << "Ошибка при записи файла!" << endl;
            return FreeData();
        }
    } while (!fEOF);

    FreeData();
    if (!DeleteFile(Source))
    {
        cout << "Удалите файл crypt.tmp вручную!" << endl;
    }
    cout << "Выполнено успешно!" << endl;
    return 0;
}

int FreeData()
{
    // закрываем файлы
    if (hSourceFile) CloseHandle(hSourceFile);
    if (hDestinationFile) CloseHandle(hDestinationFile);

    // освобождаем память
    if (Buffer) delete[] Buffer;

    // удаляем обекты
    if (hHash)
    {
        if (!(CryptDestroyHash(hHash)))
            cout << "Ошибка при выполнении CryptDestroyHash!" << endl;
        hHash = NULL;
    }

    // удаляем сессионный ключ 
    if (hKey)
    {
        if (!(CryptDestroyKey(hKey)))
            cout << "Ошибка при выполнении CryptDestroyKey!" << endl;
    }

    // удаляем провайдер
    if (hProv)
    {
        if (!(CryptReleaseContext(hProv, 0)))
            cout << "Ошибка при выполнении CryptReleaseContext!" << endl;
    }
    return 0;
}
Соседние файлы в папке решения