Консультация № 168354
26.05.2009, 22:09
0.00 руб.
0 2 2
Нигде не могу найти опубликованные коды реализации криптоалгоритма 3DES.
По словам преподавателя в университете, они существуют.
Собственно, как можно реализовать алгоритм 3DES в C++,
скажем для шифрования сообщения, предположим вводимого в программе (или файла)?

Обсуждение

Неизвестный
26.05.2009, 22:33
общий
это ответ
Здравствуйте, Ishly.
пот пример : www.amv007.narod.ru/DES3DES.ZIP

Приложение:
www.amv007.narod.ru/DES3DES.ZIP
5
Спасибо, как я понял, это будет выполняться в console application...<br><br>Если так, то builder ругается на строку: friend triple_des;<br>И пишет: Friends must be function of classes.<br><br>Только не понятно почему, ведь ранее "triple_des" был задан "как class".
Неизвестный
29.05.2009, 16:11
общий
это ответ
Здравствуйте, Ishly.
Хотелось бы Вам показать как это можно сделать в знакомой(наверное) Вам ОС Windows.
Дело в том, что Windows имеет в своем составе интерфейс CryptoAPI. И поддерживает большинство популярных алгоритмов шифрования данных. Например: AES,DES,3DES,RSA,Diffie-Hellman и др.
Пример программы:
Код:

#include <locale>
#include <iostream>
#include <iomanip>
#include <string>
#include <Windows.h>

using namespace std;

int main()
{
locale::global(locale("russian_russia.866"));

// Введем строку для шифрования
wcout<<L"Введите строку, какую Вы хотели бы зашифровать(secret):"<<endl;
wstring secret;
getline(wcin,secret);

// Буфер для работы алгоритмов шифрования
BYTE* buffer;

try
{
// Размер строки в памяти
size_t strAllocSize=sizeof(wstring::value_type)*secret.length();
// Размер буфера должен быть немного больше
size_t bufferSize=strAllocSize+8;
// Выделяем память под буфер
buffer=new BYTE[bufferSize];

#pragma warning(disable:4996)
// Копируем строку в буфер
secret.copy(reinterpret_cast<wstring::value_type*>(buffer),secret.length(),0);
#pragma warning(default:4996)

// Crypto Sevice Provider
HCRYPTPROV provider;
// Попытаемся получить CSP
if(!CryptAcquireContext(&provider,0,MS_ENHANCED_PROV,PROV_RSA_FULL,0))
{
throw L"Не получилось получить CSP";
}

// Ключ для шифрования
HCRYPTKEY key;
// Сгенерируем ключ
if(!CryptGenKey(provider,CALG_3DES,CRYPT_EXPORTABLE,&key))
{
throw L"Ошибка генерации ключа";
}

// Демонстрация экспорта ключа
// Для работы этой программы не нужна, но если есть желание
// расшифровать данные где то еще, то ключ необходим

// Сюда будем экспортировать
BYTE* keyBlob=0;
// Длина ключа
DWORD keyBlobLength=0;
// Получим размер ключа
if(!CryptExportKey(key,0,PLAINTEXTKEYBLOB,0,0,&keyBlobLength))
{
throw L"Не получилось вычислить длину ключа";
}
// Выделим память для ключа
keyBlob=new BYTE[keyBlobLength];
// Экспорт ключа
if(!CryptExportKey(key,0,PLAINTEXTKEYBLOB,0,keyBlob,&keyBlobLength))
{
throw L"Не получилось экспортировать ключ";
}

// Распечатаем его
wcout<<endl<<L"Сгенерирован ключ(hex):"<<endl;
for(size_t i=0;i<keyBlobLength;++i)
{
wcout<<hex<<keyBlob[i];
}
wcout<<endl;
// Освободим память за ненадобностью
delete[] keyBlob;

// Размер наших данных для шифрования
DWORD dataSize=strAllocSize;
// Шифруем
if(!CryptEncrypt(key,0,true,0,buffer,&dataSize,bufferSize))
{
throw L"Зашифровать данные не удалось";
}

// Распечатаем то, что у нас получилось
wcout<<endl<<L"Зашифрованная строка(hex):"<<endl;
for(size_t i=0;i<dataSize;++i)
{
wcout<<hex<<buffer[i];
}

// Попробуем расшифровать
wcout<<endl<<endl
<<L"Попробуем ее расшифровать:"<<endl;
if(!CryptDecrypt(key,0,true,0,buffer,&dataSize))
{
throw L"Расшифровать данные не получилось";
}

// Соберем результирующую строку
wstring received(reinterpret_cast<wchar_t*>(buffer),reinterpret_cast<wchar_t*>(buffer+dataSize));
wcout<<L"Расшифрованные данные(received):"<<endl;
wcout<<received<<endl;
wcout<<endl<<L"Проверим совпадают ли строки(хотя и так это видно)"<<endl
<<L"(secret==received)="<<boolalpha<<(secret==received)<<endl;
}
catch (bad_alloc)
{
wcout<<L"Ошибка выделения памяти"<<endl;
}
catch(const wchar_t* const msg)
{
wcout<<L"Исключение:"<<msg<<endl;
}
if(buffer)
{
delete[] buffer;
}
system("PAUSE");
return 0;
}

Пример работы программы:
Код:

Введите строку, какую Вы хотели бы зашифровать(secret):
Это очень-очень секретное сообщение :)

Сгенерирован ключ(hex):
82003660018000f2161207d1afe8ca25e70a81c375d54c42c3238d5f79d

Зашифрованная строка(hex):
42a76e31075d3c3eabd5ad9c3be2e092ff5f28f34144f383633e38e382b858ec84398958b2b92fb4
25539e19dc64697ee834c891d8a7ce5945a935bb6aee5d3e7b49a45be07797c8adcd8391276f

Попробуем ее расшифровать:
Расшифрованные данные(received):
Это очень-очень секретное сообщение :)

Проверим совпадают ли строки(хотя и так это видно)
(secret==received)=true
5
Форма ответа