Форум программистов CodeGuru
20 Июнь 2018, 13:21:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: CryptoAPI, Delphi: Что нужно изменить в проге, чтоб стал мой вариант (задание по  (Прочитано 21397 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Fissa
Новичок
*
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« : 22 Октябрь 2010, 18:13:47 »

Здравствуйте.
Помогите, пожалуйста, исправить нужные места в проге, чтобы она стала удовлетворять условиям моего варианта задания.

Язык программирования - Delphi - в данном случае не особо важно, т.к. просмотреть и исправить нужно часть, связанную с CryptoAPI.

Прога использует некий файл ФФФ. Этот файл ФФФ должен быть зашифрован при помощи функций криптографического интерфейса операционной системы Windows (CryptoAPI) с использованием сеансового ключа, генерируемого на основе вводимой пользователем парольной фразы.
1. При запуске программы появляется окно с вводом той самой парольной фразы, на её основе создается сеансовый ключ.
а) Далее, если файла ФФФ нет на диске, прога создает временный файл ККК.
б) Если же файл ФФФ уже существует, то с помощью созданного сеансового ключа он расшифровывается во временный файл ККК, затем проверяется "правильность" парольной фразы (по наличию записи ADMIN - не суть).
2. Прога работает с файлом ККК: читает, изменяет его содержимое...
3. После завершения работы проги файл ККК зашифровывается в файл ФФФ, затем временный файл ККК удаляется.

Варианты использования алгоритмов шифрования и хеширования выбираются в соответствии с выданным преподавателем заданием.

Мой вариант задания:
Тип симметричного шифрования - Блочный
Используемый режим шифрования - Обратная связь по шифротексту
Добавление к ключу случайного значения - Да
Используемый алгоритм хеширования - MD2

Для доступа к функциям CryptoAPI следует использовать интерфейсный модуль wincrypt.pas, полученый от преподавателя.

Во этом архиве находится весь проект проги: http://file.qip.ru/file/6d7wPaDi/5553.html ( 273,86 Кб )

Если не хотите скачивать, то вот
wincrypt.pas
Код:
1. unit Wincrypt;
2. interface
3. uses Windows;

4. const
5. //коды криптографических алгоритмов
6. CALG_MD2=$8001;
7. CALG_MD4=$8002;
8. CALG_MD5=$8003;
9. CALG_SHA=$8004;
10. CALG_RC2=$6602;
11. CALG_RC4=$6801;
12. //константы для функции CryptAcquireContext
13. PROV_RSA_FULL=1;
14. CRYPT_NEWKEYSET=$8;
15. //константы для функции создания ключа
16. CRYPT_EXPORTABLE=$1;
17. CRYPT_CREATE_SALT=$4;
18. AT_SIGNATURE= 2;
19. //константы для функции установки параметров ключа
20. KP_MODE=4;
21. //коды режимов шифрования
22. CRYPT_MODE_CBC=1;
23. CRYPT_MODE_ECB=2;
24. CRYPT_MODE_CFB=4;
25. type
26. ALG_ID=Cardinal;

27. //функции CryptoAPI
28. function CryptAcquireContext(
29. var hProv:THandle;
30. pszContainer,pszProvider:PChar;
31. dwProvType,dwFlags:Longint):Longbool;
32. stdcall; external 'advapi32' name 'CryptAcquireContextA';
33. function CryptCreateHash(
34. hProv:THandle;
35. Algid:ALG_ID;
36. hKey:THandle;
37. dwFlags:Longint;
38. var hHash:THandle):Longbool;
39. stdcall; external 'advapi32';
40. // и т.д.
41. function CryptHashData(
42. ...
43. function CryptDestroyHash(
44. ...
45. function CryptDeriveKey(
46. ...
47. function CryptDestroyKey(
48. ...
49. function CryptReleaseContext(
50. ...
51. function CryptEncrypt(
52. ...
53. function CryptDecrypt(
54. function CryptSetKeyParam(
55. function CryptGenKey(
56. function CryptGetUserKey(
57. function CryptSignHash(
58. function CryptVerifySignature(

59. implementation
60. end.

а вот и сам код проги (наконец то  ) :
Код:
   ...
1. type
2. MyType = record         
3. Login: string[20];   
4. Password: string[20];
5. Blocked: Boolean;     
6. Limited: Boolean;     
7. end;

8. var
9. Form1: TForm1;
10. User: MyType;           
11. MyFile: file of MyType;   
12. Param,Len: Longint;
13. File01,File02: File;
14. Buf: array[1..128] of Byte;
15. hProv,hKey,hHash: THandle;
...
16. procedure TForm1.FormCreate(Sender: TObject);
17. begin
18.    Param:=CRYPT_MODE_CFB;
19.    hProv:=0;
20.    Application.CreateForm(TPasswordDlg,PasswordDlg);
21.    try
22.       if not CryptAcquireContext(hProv,Nil,Nil,PROV_RSA_FULL,0) then
23.          if GetLastError=Cardinal(NTE_BAD_KEYSET) then
24.             CryptAcquireContext(hProv,Nil,Nil,PROV_RSA_FULL,CRYPT_NEWKEYSET)
25.          else Raise Exception.Create('Ошибка при доступе к CryptoAPI!');
26.       if PasswordDlg.ShowModal<>mrOk then
27.          Raise Exception.Create('Работа программы невозможна!');
28.       CryptCreateHash(hProv,CALG_MD2,0,0,hHash);
29.       CryptHashData(hHash,PChar(PasswordDlg.Password.Text),
30.       Length(PasswordDlg.Password.Text),0);
31.       PasswordDlg.Destroy;
32.       CryptDeriveKey(hProv,CALG_RC2,hHash,CRYPT_EXPORTABLE,hKey);
33.       CryptSetKeyParam(hKey,KP_MODE,@Param,0);
34.       CryptDestroyHash(hHash);
35.    Except on E:Exception do
36.          begin
37.             PasswordDlg.Destroy;
38.             if hProv<>0 then CryptReleaseContext(hProv,0);
39.             Application.ShowException(E);
40.             Application.Terminate;
41.             Exit;
42.          end;
43.    end;
44.    AssignFile(File01,'MyFile.db');
45.    AssignFile(File02,'temp.db');
46.    AssignFile(MyFile, 'temp.db');
47.    if not FileExists('MyFile.db') then
48.    begin
49.       Rewrite(MyFile);
50.       User.Login:='ADMIN';
51.       User.Password:='';
52.       User.Blocked:=False;
53.       User.Limited:=True;
54.       Write(MyFile,User);
55.       CloseFile(MyFile);
56.    end
57.    else
58.    begin
59.       Reset(File01,1);
60.       Rewrite(File02,1);
61.       repeat
62.          BlockRead(File01,Buf,sizeof(Buf),Len);
63.          CryptDecrypt(hKey,0,Eof(File01),0,@Buf,Len);
64.          BlockWrite(File02,Buf,Len);
65.       until Eof(File01);
66.       CloseFile(File01);
67.       CloseFile(File02);
68.       Reset(MyFile);
69.       Read(MyFile,User);
70.       CloseFile(MyFile);
71.       if User.Login<>'ADMIN' then
72.       begin
73.          CryptDestroyKey(hKey);
74.          CryptReleaseContext(hProv,0);
75.          ShowMessage('Неверный ключ расшифрования!');
76.          DeleteFile('temp.db');
77.          Application.Terminate;
78.          Exit;
79.       end;
80.    end;
81. end;

82. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
83. begin
84.    Reset(File02,1);
85.    Rewrite(File01,1);
86.    repeat
87.       BlockRead(File02,Buf,sizeof(Buf),Len);
88.       CryptEncrypt(hKey,0,Eof(File02),0,@Buf,Len,sizeof(Buf));
89.       BlockWrite(File01,Buf,Len);
90.    until Eof(File02);
91.    CloseFile(File01);
92.    CloseFile(File02);
93.    DeleteFile('temp.db');
94.    CryptDestroyKey(hKey);
95.    CryptReleaseContext(hProv,0);
96. end;
Записан
Fissa
Новичок
*
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« Ответ #1 : 23 Октябрь 2010, 10:19:44 »

Дополненительные пояснения:

1. алгоритм хеширования - MD2 - это я и так сделала - вставила CALG_MD2 вместо CALG_MD5 как изначально было

2. режим шифрования - Обратная связь по шифротексту - тоже сделала - вставила CRYPT_MODE_CFB вместо CRYPT_MODE_CBC как изначально было

3. Мне надо проверить только:
Тип симметричного шифрования - Блочный (а не Потоковый)
Добавление к ключу случайного значения - Да (а не Нет Улыбка )

Если б мне подсказали хоть где это вообще смотреть (мож в каких функциях CryptoAPI).

Хотя бы просто СКАЖИТЕ, у меня БЛОЧНОЕ ШИФРОВАНИЕ В ПРОГЕ ИЛИ НЕТ и ЕСТЬ ЛИ В ПРОГЕ ДОБАВЛЕНИЕ К КЛЮЧУ СЛУЧАЙНОГО ЗНАЧЕНИЯ?
« Последнее редактирование: 23 Октябрь 2010, 10:25:06 от Fissa » Записан
Fissa
Новичок
*
Офлайн Офлайн

Сообщений: 3


Просмотр профиля
« Ответ #2 : 23 Октябрь 2010, 15:06:08 »

Усё, я разобралась:
1. Тип симметричного шифрования - Блочный.
Это надо смотреть RC2 (Блоковый алгоритм шифрования) либо RC4 (Потоковый алгоритм шифрования). У меня в проге всё правильно - CALG_RC2.
2. Добавление к ключу случайного значения.
Это надо в функции CryptDeriveKey вместо параметра CRYPT_EXPORTABLE использовать фразу CRYPT_EXPORTABLE or CRYPT_CREATE_SALT.

Вот и весь ответ. Тема закрыта.

P.S.: Пришлось прочесть немало литературы, чтобы разобраться в CryptoAPI и в данном мне задании.
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #3 : 23 Октябрь 2010, 21:10:32 »

Усё, я разобралась:

P.S.: Пришлось прочесть немало литературы, чтобы разобраться в CryptoAPI и в данном мне задании.

грац ! Улыбка
Интересная тема, жаль что вчера на форуме не был  Грустный

2. Добавление к ключу случайного значения.
Это надо в функции CryptDeriveKey вместо параметра CRYPT_EXPORTABLE использовать фразу CRYPT_EXPORTABLE or CRYPT_CREATE_SALT.

Хм... насколько я понимаю, CRYPT_CREATE_SALT не вызывает добавление к ключу случайного значения (да и зачем к ключу добавлять значение, получится же другой ключ). Этот флаг указывает на необходимость сохранения "хвоста" данных, из которых генерируется сессионный ключ.
Суть примерно такая (судя по описанию CryptDeriveKey в MSDN). Сессионный ключ генерируется на основе хеша. Хеш может быть, например, 128 бит длиной, а ключ нужно получить 40 бит длиной. Так вот, если при вызове CryptDeriveKey будет указан флаг CRYPT_CREATE_SALT, то остаток в 88 бит после генерации ключа будет сохранен. И его потом можно будет получить с помощью вызова CryptGetKeyParam, которой в качестве dwParam нужно передать KP_SALT.

З.Ы. сам когда-то разбирался с CryptoAPI (правда было это лет 11 или 12 назад).
Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!