Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Шифрование\разшифрование файлов


Автор: Kirgston 12.5.2009, 16:23
Всем доброго времени суток! Вот на делфях у меня была библиотека для работы с файлами и просто строками (шифрование\разшифрование). Просто забыл название... и не могу вспомнить :(

Вот как обявлял...

Код

uses
DCPrc6, DCPsha1;

    function EncryptString(Source, Password: string): string;
    function DecryptString(Source, Password: string): string;
    function DecryptFile(Source, Dest, Password: string): Boolean;
    function EncryptFile(Source, Dest, Password: string): Boolean;

function TForm3.EncryptFile(Source, Dest, Password: string): Boolean;
var
  DCP_rc: TDCP_rc6;
  SourceStream, DestStream: TFileStream;
begin
  Result := True;
  try
    SourceStream := TFileStream.Create(Source, fmOpenRead);
    DestStream := TFileStream.Create(Dest, fmCreate);
    DCP_rc := TDCP_rc6.Create(Self);
    DCP_rc.InitStr(Password, TDCP_sha1);
    DCP_rc.EncryptStream(SourceStream, DestStream, SourceStream.Size);
    DCP_rc.Burn;
    DCP_rc.Free;
    DestStream.Free;
    SourceStream.Free;
  except
    Result := False;
  end;
end;

function TForm3.EncryptString(Source, Password: string): string;
var
  DCP_rc: TDCP_rc6;
begin
  DCP_rc := TDCP_rc6.Create(Self);   // создаём объект
  DCP_rc.InitStr(Password, TDCP_sha1);
  Result := DCP_rc.EncryptString(Source); // шифруем
  DCP_rc.Burn;                            // стираем инфо о ключе
  DCP_rc.Free;                            // уничтожаем объект
end;


function TForm3.DecryptFile(Source, Dest, Password: string): Boolean;
var
  DCP_rc: TDCP_rc6;
  SourceStream, DestStream: TFileStream;
begin
  Result := True;
  try
    SourceStream := TFileStream.Create(Source, fmOpenRead);
    DestStream := TFileStream.Create(Dest, fmCreate);
    DCP_rc := TDCP_rc6.Create(Self);
    DCP_rc.InitStr(Password, TDCP_sha1);
    DCP_rc.DecryptStream(SourceStream, DestStream, SourceStream.Size);
    DCP_rc.Burn;
    DCP_rc.Free;
    DestStream.Free;
    SourceStream.Free;
  except
    Result := False;
  end;
end;

function TForm3.DecryptString(Source, Password: string): string;
var
  DCP_rc: TDCP_rc6;
begin
  DCP_rc := TDCP_rc6.Create(Self);   // создаём объект
  DCP_rc.InitStr(Password, TDCP_sha1);    // инициализируем
  Result := DCP_rc.DecryptString(Source); // дешифруем
  DCP_rc.Burn;                            // стираем инфо о ключе
  DCP_rc.Free;                            // уничтожаем объект
end;


И это... подскажите хорошие либы для шифрования\дешифрации 

Заранее больше спасибо!

Автор: artsb 12.5.2009, 16:58
Kirgston, глянь http://algolist.manual.ru/.

Автор: Alca 12.5.2009, 17:36
http://www.openssl.org/

Автор: vikaz 12.5.2009, 18:01
Цитата(Kirgston @  12.5.2009,  16:23 Найти цитируемый пост)
И это... подскажите хорошие либы для шифрования\дешифрации 

CryptoAPI. 

http://forum.vingrad.ru/forum/topic-243538.html

Автор: Kirgston 12.5.2009, 19:05
Ребята спасибо вам за полезную информацию. Остановился я на Крипто ++ . Вроде всё что надо - есть =) а вот посмотреть как работать с ней не могу :( мануал на сайте не доступен... в гугле также примеров не нашёл... может кто то раскажет? Или примерчик?  smile 

Автор: artsb 12.5.2009, 20:24
Цитата(Kirgston @  12.5.2009,  19:05 Найти цитируемый пост)
примерчик?

http://forum.vingrad.ru/forum/topic-243538.html#st_15_view_0

Автор: Kirgston 12.5.2009, 20:45
Да видел... но я что то не заметил чтобы были какие-либо обращения к Crypt++. Вот например я первый раз буду работать с этой либой. Я ничего не понимаю что и куда ))) с гугле воооообще ничего не нашёл :( ниодного примера :( а этот пример вроде работает с CryptAPI...

Автор: artsb 12.5.2009, 22:26
Kirgston, ты букву о потерял smile Crypto++

Вот пара ссылок:
http://www.rsdn.ru/forum/message/172861.flat.aspx#172861
http://rfd.rsdn.ru/forum/message/1237553.flat.aspx
http://ftp.rsdn.ru/forum/message/1512780.flat.aspx#1512780
http://rfd.rsdn.ru/forum/message/1060276.aspx - объемная тема

Там есть такая особенность - может отображаться только первый пост. Чтобы увидеть остальные клацни по кнопке "Посмотреть все ответы темы".

Автор: Kirgston 12.5.2009, 22:34
О пасибки! Действительно )))))) потерял и смотрю что ничего нету )))))) а ещё смежный вопросик... а вот по теме которую вы мне дали. Там есть пример. Так какая там шифрация? Мне бы например хотелось RC6 но там вроде "самопал" ?

Автор: artsb 12.5.2009, 22:55
Цитата

а вот по теме которую вы мне дали

Какая ссылка?

Цитата(Kirgston @  12.5.2009,  22:34 Найти цитируемый пост)
RC6

http://softsearch.ru/programs/14-386-rc6-s-c-library-download.shtml
http://forum.shelek.ru/index.php/topic,7210.0.html
http://www.delphisources.ru/pages/faq/base/rc6_encryption.html smile

Автор: mrbrooks 13.5.2009, 08:05
Kirgston, не знаю советовали или нет - по ссылкам влом гулять но в 2009 версии Борман предлагает свое решение.

EncodeStream/DecodeStream
EncodeString/DecodeString
EncodeBase64/DecodeBase64

Живет вся эта красота не земная в EncdDecd.hpp. Очень кошерный функционал.

Автор: xvr 13.5.2009, 14:43
Цитата(mrbrooks @ 13.5.2009,  08:05)
Kirgston, не знаю советовали или нет - по ссылкам влом гулять но в 2009 версии Борман предлагает свое решение.

EncodeStream/DecodeStream
EncodeString/DecodeString
EncodeBase64/DecodeBase64

Живет вся эта красота не земная в EncdDecd.hpp. Очень кошерный функционал.

Это все банальный base64 - с шифрованием не имеет НИЧЕГО общего

Автор: mrbrooks 13.5.2009, 15:10
Цитата(xvr @  13.5.2009,  14:43 Найти цитируемый пост)
Это все банальный base64 - с шифрованием не имеет НИЧЕГО общего

Это для тебя банальный, для автора, возможно, будет достаточно.

Автор: xvr 13.5.2009, 17:06
Цитата(mrbrooks @ 13.5.2009,  15:10)
Цитата(xvr @  13.5.2009,  14:43 Найти цитируемый пост)
Это все банальный base64 - с шифрованием не имеет НИЧЕГО общего

Это для тебя банальный, для автора, возможно, будет достаточно.

Автор хотел RC6, так что base64 будет явно недостаточно. Тогда уж лучше запаковать (например через zlib), и то будет более похоже на шифрование  smile 

Автор: mrbrooks 14.5.2009, 08:00
Цитата(xvr @  13.5.2009,  17:06 Найти цитируемый пост)
Тогда уж лучше запаковать (например через zlib), и то будет более похоже на шифрование

согласный. он, кстати, в 2009 тоже уже живет. В старых версиях - не помню.

Автор: Kirgston 14.5.2009, 14:05
Ребята я очень признателен что вы помогаете такому оболдую как я! А не могли бы вы написать маленький примерчик с Крипто++ ?... а то я что то его понять совсем не могу... как с ним работать?... очень прошу помочь! =) просто с прошлой либой (пример которой я выложил в верху для Делфи) проблем небыло вообще!... там и мануал нормальный и примеры... а тут просто кусок библиотеки. Как хочешь так и работай :( . Особенно если я не спец... то мне очень тяжело... помогите пожалуйста!  smile 

Автор: xvr 14.5.2009, 16:19
Цитата(Kirgston @ 14.5.2009,  14:05)
А не могли бы вы написать маленький примерчик с Крипто++ ?... а то я что то его понять совсем не могу... как с ним работать?... 

Сюда http://www.cryptopp.com/wiki/User_Guide:_cryptlib.h смотрел?

Автор: Kirgston 14.5.2009, 22:10
Извините не нашёл =) щас изучал внимательно... на сколько я вижу там нету шифрования... там есть рандомное число, есть взять хеш или как его там =) ну контрольную сумму... а примера шифрования нету :( очень жаль что нету понятного мануала :( я то понимаю что профи разобратся легко, но не чайникам. Бегал по форумах и смотрел что очень много людей не знают как работать с либой. Даже те кто хорошо знает криптографию имеют проблемы :(

Автор: artsb 14.5.2009, 22:56
Цитата(Kirgston @  14.5.2009,  22:10 Найти цитируемый пост)
очень много людей не знают как работать с либой. Даже те кто хорошо знает криптографию имеют проблемы :( 

Может тогда выбрать другую.  smile Проверенную временем. smile 

Автор: Alca 14.5.2009, 23:05
Цитата

Может тогда выбрать другую.  

Какую?

Автор: artsb 15.5.2009, 00:21
Цитата(Alca @  14.5.2009,  23:05 Найти цитируемый пост)
Какую?

Я ими никогда не пользовался (не было необходимости), но больше чем уверен, что их много. И тут уже, что Kirgston выберет.

Автор: mrbrooks 15.5.2009, 07:47
Kirgston, да не парься камрад. делай как я посоветовал, если срочно надо - в свободное же время планомерно изучай доки к этому Cripto имхо.

Автор: xvr 15.5.2009, 10:10
Цитата(Kirgston @ 14.5.2009,  22:10)
Извините не нашёл =) щас изучал внимательно... на сколько я вижу там нету шифрования... там есть рандомное число, есть взять хеш или как его там =) ну контрольную сумму... а примера шифрования нету :( очень жаль что нету понятного мануала :( я то понимаю что профи разобратся легко, но не чайникам. Бегал по форумах и смотрел что очень много людей не знают как работать с либой. Даже те кто хорошо знает криптографию имеют проблемы :(

Тебе нужен http://www.cryptopp.com/wiki/User_Guide:_filters.h#StreamCipherFilter. 
Еще - http://www.cryptopp.com/wiki/User_Guide:_eccrypto.h  http://www.cryptopp.com/wiki/User_Guide:_rsa.h
и отсюда и далее - http://www.cryptopp.com/wiki/User_Guide:_Header_Files#Stream_Ciphers


Автор: Kirgston 15.5.2009, 19:57
Пасибки ребятки! =) щас буду потихоньку всё читать и изучивать =) может что то и толковое получится =)

Автор: Kirgston 16.5.2009, 18:52
Ребята как я вижу Crypto++ и Crypto API вроде похожи. Ну то есть АПИ - встроено в винде, ++ вроде какбы имеет свою библиотеку. Но у меня такой вопросик... что лучше изучать? Что надёжней? Большая ли разница в надёжности? Спасибо!

Автор: xvr 16.5.2009, 21:31
Цитата(Kirgston @ 16.5.2009,  18:52)
Ребята как я вижу Crypto++ и Crypto API вроде похожи. 

Кроме слова 'Crypto' в названии больше ничего общего нет  smile 
Цитата

Ну то есть АПИ - встроено в винде, ++ вроде какбы имеет свою библиотеку. 
Угу
Цитата

Но у меня такой вопросик... что лучше изучать? 
Ну и вопросик. Ответ будет - это зависит от .... Мультиплатформенность нужна? Открытые сорцы нужны?
Цитата

Что надёжней? Большая ли разница в надёжности?
Разницы нет. По крайней мере ты вряд ли эту разницу сможешь найти (если она даже и будет)

Автор: Kirgston 16.5.2009, 22:21
Цитата(xvr @  16.5.2009,  21:31 Найти цитируемый пост)
Кроме слова 'Crypto' в названии больше ничего общего нет

Ой пардон! Просто исходил от того что название похоже + и то шифрует и то =)

Цитата(xvr @  16.5.2009,  21:31 Найти цитируемый пост)
Ну и вопросик. Ответ будет - это зависит от .... Мультиплатформенность нужна? Открытые сорцы нужны?

Неа =) ни то ни то =) разве вся мультиплатформенность сводится к поддержке 98го =) а если по реальней надо просто чтобы работало на платформах Вин серв, ХР, Виста , Вин 7, ну и на 64ех битниках, маки, линуксы, юники и т.д. не нужны =)

Автор: xvr 17.5.2009, 10:18
Цитата(Kirgston @ 16.5.2009,  22:21)
Цитата(xvr @  16.5.2009,  21:31 Найти цитируемый пост)
Ну и вопросик. Ответ будет - это зависит от .... Мультиплатформенность нужна? Открытые сорцы нужны?

Неа =) ни то ни то =) разве вся мультиплатформенность сводится к поддержке 98го =) а если по реальней надо просто чтобы работало на платформах Вин серв, ХР, Виста , Вин 7, ну и на 64ех битниках, маки, линуксы, юники и т.д. не нужны =)

Тогда лучше взять CryptoAPI, оно все же встроенное. А еще лучше взять CAPICOM, он проще, чем CryptoAPI

Автор: Kirgston 17.5.2009, 10:29
Спасибо большое! =) Ну мне главное не как простота... а надёжность =) если надо будет сильно посидеть и попотеть то уж никуда не денусь =) для меня главное качество а не скорость ;)

Автор: xvr 17.5.2009, 12:31
Цитата(Kirgston @ 17.5.2009,  10:29)
Спасибо большое! =) Ну мне главное не как простота... а надёжность =) если надо будет сильно посидеть и попотеть то уж никуда не денусь =) для меня главное качество а не скорость ;)

Все эти API реализуют одни и те же  алгоритмы, так что качество у них одинаковое.
Бери то, что проще применить

Автор: Alca 19.5.2009, 10:59
http://temp.rsdn.ru/Forum/Info/FAQ.mfc.wincrypto.aspx

Автор: Kirgston 23.5.2009, 09:40
Цитата(Alca @  19.5.2009,  10:59 Найти цитируемый пост)
[MFC] CWinCrypto

Пасибки но как вы заметили тут Билдер =)

Ребята... вот нашёл статейку http://www.rsdn.ru/article/crypto/usingcryptoapi.xml
Вроде ознакомился со всем =)

Но вот у меня возникла проблемка.

Код

HCRYPTPROV hProv;
HCRYPTKEY hSessionKey;

// Получение контекста криптопровайдера
if (!CryptAcquireContext(&hProv, NULL, NULL, 
    PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
  Error("CryptAcquireContext");
  return;
}

std::cout << "Cryptographic provider initialized" << std::endl;

// Генерация сессионного ключа
if (!CryptGenKey(hProv, CALG_RC4, 
    CRYPT_ENCRYPT | CRYPT_DECRYPT, &hSessionKey))
{
  Error("CryptGenKey");
  return;
}

std::cout << "Session key generated" << std::endl;

// Данные для шифрования
char string[]="Test";
DWORD count=strlen(string);

// Шифрование данных
if (!CryptEncrypt(hSessionKey, 0, true, 0, (BYTE*)string, 
    &count, strlen(string)))
{
  Error("CryptEncrypt");
  return;
}

std::cout << "Encryption completed" << std::endl;

// Тестовый вывод на экран
std::cout << "Encrypted string: " << string << std::endl;


Запускаю... и... вижу странную штуку... если консольное приложение то всё проходит на 90% ура. Но после криптовки текста ... текст выходит...выходит... а выходит он таким каким и вошёл... то есть
char string[]="Test";
std::cout << "Encryption completed" << std::endl//так же будет Тест... ничего вообще какбудто не произошло....

Потом сделал уже форменное приложение а там оно мне начало ругатся... точнее не хотело генерировать ключик. Почему - незнаю... всё сделал как было представлено в мануале. 

Может мануал не такой? =) не подходящий? =) может есть какие - либо другие? =) Заранее очень благодарен
 

Автор: xvr 23.5.2009, 18:43
Цитата(Kirgston @ 23.5.2009,  09:40)
Запускаю... и... вижу странную штуку... если консольное приложение то всё проходит на 90% ура. Но после криптовки текста ... текст выходит...выходит... а выходит он таким каким и вошёл... то есть
char string[]="Test";
std::cout << "Encryption completed" << std::endl//так же будет Тест... ничего вообще какбудто не произошло....

Должно работать. Программа точно выглядит именно так? Проверки на ошибки правильные?
Цитата

Потом сделал уже форменное приложение а там оно мне начало ругатся... точнее не хотело генерировать ключик. Почему - незнаю... всё сделал как было представлено в мануале. 
Где и какие ошибки выдает?

Автор: Kirgston 23.5.2009, 19:29
Ну да именно так =) точнее вместо Error (ошибка) я её вывожу. Типа cout<<key gen error . 

Ну не ошибки... но скажем просто ничего не происходит. Я взял и вписал как там было if (!...) и мне выбило типа ошибка генерации ключа. То есть не программная ошибка. А просто в случае если ключ не сгенится то я вывожу что нету ключа. Так именно и вывело =) нету ключа =)

Автор: Kirgston 23.5.2009, 22:13
Вот посмотрите сами... почему так я сам не знаю...

Автор: xvr 23.5.2009, 22:59
Цитата(Kirgston @ 23.5.2009,  22:13)
Вот посмотрите сами... почему так я сам не знаю...

Посмотрел. Правда 2009 CG у меня нет, собрал на 2006. Все работает, ключи генерит, текст шифрует.
Я вставил вместо последней строки в программе это:
Код

AnsiString acc;
for(int i=0;i<count;++i) acc.cat_printf("%02X",(unsigned char)string[i]);
RichEdit1->Lines->Add(acc);
получил 565A7594 или 3A7366B5 или 6A7BF188 и т.д.
Может какие то заморочки с Unicode'ом в CG 2009?

Автор: Kirgston 23.5.2009, 23:31
хе хе ))) 

Cryptographic provider initialized
CryptGenKey Error
Session key generated
CryptEncrypt Error
Encryption completed
Encrypted string: 
54657374

каждый раз получаю одну и ту же строку =)не знаете изза чего это может быть?

Автор: xvr 24.5.2009, 09:29
Цитата(Kirgston @ 23.5.2009,  23:31)
каждый раз получаю одну и ту же строку =)не знаете изза чего это может быть?

Из за этого - 
Цитата

CryptGenKey Error
CryptEncrypt Error
Добавь это 
Код

AnsiString e()
{
 char buff[1000];
 HRESULT hr=GetLastError();
 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,hr,
               MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
               buff,1000,NULL))
  return AnsiString().sprintf("%08X: %s",hr,buff).Trim();
 return AnsiString().sprintf("%08X",hr);
}

и это перед всеми 'Error' выдачами
Код

 RichEdit1->Lines->Add(e());

Посмотрим, что за ошибки   smile 

Автор: Kirgston 24.5.2009, 10:54
Получил :

Cryptographic provider initialized
80090022: Поставщик не смог выполнить действие, поскольку контекст был получен как "тихий".
CryptGenKey Error
Session key generated
00000057: Параметр задан неверно.
CryptEncrypt Error
Encryption completed
Encrypted string: 
54657374

о_О а что такое тихий контекст? )))

Автор: Kirgston 24.5.2009, 11:20
А да и кстати... вот в компоненте RichEdit есть 2 входящих параметра при записи\чтении в\из потока. Первый непосредственно сам поток, а второй TEncode *Encode . Что такое этот второй параметр? =) это же вроде так же крипт? Конечно я не говорю что он мне сейчас подходит, но просто стало интересно т.к. раньше даже не замечал его =)

Автор: xvr 24.5.2009, 23:14
Цитата(Kirgston @ 24.5.2009,  10:54)
Получил :

Cryptographic provider initialized
80090022: Поставщик не смог выполнить действие, поскольку контекст был получен как "тихий".
CryptGenKey Error

о_О а что такое тихий контекст? )))

Про 'тихий' контекст сказано в описании CryptAcquireContext (точнее ее параметре flags, бит CRYPT_SILENT)
Цитата

The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT (собственно и есть ошибка 80090022) error code is set as the last error. In addition, if calls are made to CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail and the CSP sets NTE_SILENT_CONTEXT.

CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by the CSP.
У тебя его нет, а есть только CRYPT_VERIFYCONTEXT, но кто знает, попробуй и его убрать  smile 

Цитата

А да и кстати... вот в компоненте RichEdit есть 2 входящих параметра при записи\чтении в\из потока. Первый непосредственно сам поток, а второй TEncode *Encode . Что такое этот второй параметр? =) это же вроде так же крипт?
Это не крипт. Это преобразователь формата (например из plain text в RTF) В теории, если задать необходимый преобразователь, то в RichText можно будет загрузить что угодно, например HTML страницу  smile

Добавлено через 11 минут и 18 секунд
Нашел ошибку - в CryptGenKey параметры CRYPT_ENCRYPT и CRYPT_DECRYPT заданны не верно, они вообще для другой функции. Для CryptGenKey они соответствуют CRYPT_EXPORTABLE и CRYPT_USER_PROTECTED 
Для последнего написано:
Цитата

If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use this key. The precise behavior is specified by the CSP being used.If the provider context was opened with the CRYPT_SILENT flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
Еще есть опция CRYPT_FORCE_KEY_PROTECTION_HIGH, для нее написано:
Цитата

This flag specifies strong key protection. When this flag is set, the user is prompted to enter a password for the key when the key is created. The user will be prompted to enter the password whenever this key is used.

This flag is only used by the CSPs that are provided by Microsoft. Third party CSPs will define their own behavior for strong key protection.

Specifying this flag causes the same result as calling this function with the CRYPT_USER_PROTECTED flag when strong key protection is specified in the system registry.

If this flag is specified and the provider handle in the hProv parameter was created by using the CRYPT_VERIFYCONTEXT or CRYPT_SILENT flag, this function will set the last error to NTE_SILENT_CONTEXT and return zero.
Подай 0 вместо них

Автор: yudinetz 26.8.2009, 14:51
так все-таки, если провайдер просит гуи интерфейс, то что делать-то? 
у меня консольное приложение, функция CryptAcquireContext вылетает с ошибкой этого тихого контекста.

Автор: xvr 28.8.2009, 11:12
Читать мой предыдущий ответ - от 'Добавлено через 11 минут и 18 секунд' и далее

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)