Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.06.2011, 23:36   #1
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
Восклицание Шифрование алгоритмом AES (также известный как Rijndael)

Люди не проходим мимо! Помогите, кто чем сможет!
А то пролазил и этот форум и много других, и на интернет потратил больше 2 дней а результата 0.
Проблема в следующем, пишу диплом, и мне надо организовать передачу зашифрованных данных (тестовых сообщений) по сети, алгоритмом AES.
Я нашел исходник относительно нормальный, но проблема в том что он текст сохраняет в файл а потом уж для дешифрации считывает зашифрованный текст из файла, у меня как бы получилось сделать что бы он зашифровывал не в файл, а чисто так, что бы сразу передавался зашифрованное сообщение, но с реализацией расшифровки возникли проблемы, я пытался отвязать его от файла. Сделал его так что бы он не расшифровывал полученную строку, но он на дешифрации всегда выдает ошибку.
Помогите разобраться, а то я сам не в силах, или поделитесь с нормальным исходником этого алгоритма, если у кого то есть он конечно.

Вот исходни и сам проект если кому то надо посмотреть. Извиняйте что без комментов.

Код:
const
  PROV_RSA_AES = 24;
  ALG_SID_AES_128 = 14;
  CALG_AES_128 = ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_AES_128;

function encrypt(input, key: AnsiString): AnsiString;
var
  hProv: HCRYPTPROV;
  hKey: HCRYPTKEY;
  keyBlob: record
    keyHeader: BLOBHEADER;
    keySize: DWORD;
    keyData: array[0..15] of Byte; 
  end; 
  keyLen, dataLen: Integer;
  cryptMode, padMode: DWORD;

  function AlignUp(dwValue, dwAlignment: DWORD): DWORD; register;
  asm
     dec edx
     add eax,edx
     not edx
     and eax,edx
  end;

begin
  if (Length(input) = 0) then
    raise Exception.Create('[INPUT] parameter not specified.');

  if (Length(key) = 0) then
    raise Exception.Create('[KEY] parameter not specified.');
          
  if not CryptAcquireContext(@hProv, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) then
    RaiseLastOSError();

  try
    FillChar(keyBlob, SizeOf(keyBlob), 0);
    with keyBlob do
    begin
      keyHeader.bType := PLAINTEXTKEYBLOB;
      keyHeader.bVersion := CUR_BLOB_VERSION;
      keyHeader.aiKeyAlg := CALG_AES_128;
      keySize := 16;

      if (Length(key) < 16) then
        keyLen := Length(key)
      else
        keyLen := 16;

      Move(key[1], keyData[0], keyLen);
    end;

    if not CryptImportKey(hProv, @keyBlob, SizeOf(keyBlob), 0, 0, @hKey) then
      RaiseLastOSError();

    try
      cryptMode := CRYPT_MODE_CBC;
      if not CryptSetKeyParam(hKey, KP_MODE, @cryptMode, 0) then
        RaiseLastOSError();
                            
      padMode := PKCS5_PADDING;
      if not CryptSetKeyParam(hKey, KP_PADDING, @padMode, 0) then
        RaiseLastOSError();

      Result := input;
      dataLen := Length(Result);
      SetLength(Result, AlignUp(Length(Result) + 1, 16));

      if not CryptEncrypt(hKey, 0, True, 0, @Result[1], @dataLen, Length(Result)) then
        RaiseLastOSError();
                       
    finally                 
      CryptDestroyKey(hKey);
    end;
        
  finally
    CryptReleaseContext(hProv, 0);
  end;
end;

function decrypt(input, key: AnsiString): AnsiString;
var
  hProv: HCRYPTPROV;
  hKey: HCRYPTKEY;
  keyBlob: record
    keyHeader: BLOBHEADER;
    keySize: DWORD;
    keyData: array[0..15] of Byte; 
  end; 
  keyLen, dataLen: Integer;
  cryptMode, padMode: DWORD;
begin
  if (Length(input) = 0) then
    raise Exception.Create('[INPUT] parameter not specified.');

  if (Length(key) = 0) then
    raise Exception.Create('[KEY] parameter not specified.');
          
  if not CryptAcquireContext(@hProv, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) then
    RaiseLastOSError();

  try
    FillChar(keyBlob, SizeOf(keyBlob), 0);
    with keyBlob do
    begin
      keyHeader.bType := PLAINTEXTKEYBLOB;
      keyHeader.bVersion := CUR_BLOB_VERSION;
      keyHeader.aiKeyAlg := CALG_AES_128;
      keySize := 16;

      if (Length(key) < 16) then
        keyLen := Length(key)
      else
        keyLen := 16;

      Move(key[1], keyData[0], keyLen);
    end;

    if not CryptImportKey(hProv, @keyBlob, SizeOf(keyBlob), 0, 0, @hKey) then
      RaiseLastOSError();

    try
      cryptMode := CRYPT_MODE_CBC;
      if not CryptSetKeyParam(hKey, KP_MODE, @cryptMode, 0) then
        RaiseLastOSError();
                            
      padMode := PKCS5_PADDING;
      if not CryptSetKeyParam(hKey, KP_PADDING, @padMode, 0) then
        RaiseLastOSError();

      Result := input;
      dataLen := Length(Result);

      if not CryptDecrypt(hKey, 0, True, 0, @Result[1], @dataLen) then
        RaiseLastOSError();

      SetLength(Result, dataLen);
                       
    finally                 
      CryptDestroyKey(hKey);
    end;
        
  finally
    CryptReleaseContext(hProv, 0);
  end;
end;
darek13 вне форума Ответить с цитированием
Старый 14.06.2011, 23:40   #2
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

Вот код нажатия кнопок Ширфации и расшифровки

Код:
//кнопка шифрации
procedure TfrmMain.btnEcnryptClick(Sender: TObject);
var
  f: TextFile;
  cipherText: AnsiString;
begin
  edtText.text := encrypt(edtText.Text, edtKey.Text);

  AssignFile(f, 'ciphertext.txt');
  Rewrite(f);
  try
    Write(f, cipherText);
  finally
    CloseFile(f);
  end;

  MessageBox(Handle, 'Saved to ciphertext.txt.', 'Done.', MB_OK); 
end;

//нопка расшифровки
procedure TfrmMain.btnDecryptClick(Sender: TObject);
var
 f: file of Char;
  chars: array of Char;
  cbChars: Integer;
begin
 
  AssignFile(f, 'ciphertext.txt');
  Reset(f); 
  try
    cbChars := FileSize(f);
    SetLength(chars, cbChars);
    BlockRead(f, chars[0], cbChars);  
  finally
    CloseFile(f);
  end;

  edtText.Text := decrypt(edtText.TextAnsiString(chars), edtKey.Text);

  MessageBox(Handle, 'Readed from ciphertext.txt.', 'Done.', MB_OK);
end;

end.
Помогите пожалуйста реализовать так тчо бы он работал без файла, а помешал зашифрованный текст в переменную, и потом с этой переменной расшифровывал.

Вот сама прога если кому надо
Вложения
Тип файла: rar delphi AES.rar (293.7 Кб, 336 просмотров)
darek13 вне форума Ответить с цитированием
Старый 15.06.2011, 01:09   #3
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

дык, а типы? не храни в edtText.Text, заведи переменную типа ansistring:

Код:
var ss: ansistring;

procedure TfrmMain.btnEcnryptClick(Sender: TObject);
begin
 ss:= encrypt(edtText.Text, edtKey.Text);
 edtText.text := ss;
end;

procedure TfrmMain.btnDecryptClick(Sender: TObject);
begin
  edtText.Text := decrypt(ss, edtKey.Text)
end;


Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 15.06.2011, 01:38   #4
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

у меня как бы переменная есть strtmp:string; т.е. мне просто поменать ее типа, и что это за ти ansistring, если не секрет?
darek13 вне форума Ответить с цитированием
Старый 15.06.2011, 10:22   #5
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

не секрет, жмакаешь F1 - в справке все есть ...просто вы используете "свойство компонента" для хранения, а там могут быть непечатаемые символы.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 15.06.2011, 11:58   #6
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

та у меня походу сам алгоритм немного глючный, он через раз расшифровывает, может ли кто-то поделится нормальным AES алгоритмом? И подскажите когда я шифрую сообщения мне в какой тип переменной сохранять ansistring или string
darek13 вне форума Ответить с цитированием
Старый 15.06.2011, 13:32   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

1) я не знаю, насколько в вашем случае правильно реализован AES
я бы рекомендовал взять готовую бесплатную рабочую библиотечку.
например, Delphi Encryption Compendium by Hagen Reddmann

2)
Код:
мне в какой тип переменной сохранять ansistring или string
можно в AnsiString...
главное, не использовать представление Text у визуальных компонентов (Memo.Text, Edit.Text и т.п.)!
Они заточены под отображение ПЕЧАТНЫХ символов.

darek13, посмотрите, в пост #3 raxp уже абсолютно внятно и чётко Вам всё разжевал. Читайте пост #3 до полного просветления! (а оно в том, что надо использовать переменную ss и НЕ НАДО ИСПОЛЬЗОВАТЬ edtText.text )
Serge_Bliznykov вне форума Ответить с цитированием
Старый 15.06.2011, 14:43   #8
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

Serge_Bliznykov
Извиняюсь если покажется грубо, но говорю сразу это не так, просто это вы не поняли, У меня вообще все по другому реализовано.
Во первых по поводу
Цитата:
1) я не знаю, насколько в вашем случае правильно реализован AES
я бы рекомендовал взять готовую бесплатную рабочую библиотечку.
например, Delphi Encryption Compendium by Hagen Reddmann
Я думал использовать библиотеки шифрования, но я пишу диплом и мне сказали что то что я использую готовое, не засчитают надо свой алгоритм что бы был.
Во вторых, у меня передается зашифрованный текст по сети. Обьясню по подробней:
Пользователь который хочет отправить Личное Сообщенеи (ЛС), перед тем как его отправить шифрует своим ключем который состоит из 32 символом, это у нас переменная p:string (этот ключ - это хэш пароля при входе в систему, это все у клиентов), так вот когда клиент отсылает сообщение он шифрует и записывает зашифрованный текст в переменную temp:ansistring и передает даные на сервер, но при отправке сообщенеи отображется в поле чата в МЕМО но в нормально виде, по скольку там оно не шифруется. Сервер когда принимает ЛС он смотри от кого пришло и считывает с БД хэш пароля этого клиента потом берет переменную temp:ansistring где содержится зашифрованное сообщение расшифровывает его так STRTEMP:= decrypt(temp, p);, STRTEMP у меня уже типа string. и затем расшифрованное сообщение выводит в мемо. Но если сообщение не серверу, то он сначала делает все тоже самое, но смотрит кому оно предназначалось, находит этого пользователя, считывает его хэш из БД и шифрует уже расшифрованное сообщение в переменную LSUser:ansistring и отправляет уже зашифрованное опять сообщение дальше, что бы клиент мог расшифровать своим ключем. у мен все работает но через раз, иногда все отлично делает, а иногда когда сервер получает сообщение пишет ошибку что проблема с симвалами, но при этом все эти непечатные символы не имеют никакого отношения к мемо, в мемо выводится только расшифрованное сообщение, просто проблема сама в алгоритме походу
darek13 вне форума Ответить с цитированием
Старый 15.06.2011, 14:50   #9
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

А сели быть точнее то выводится вот такое сообщение
Изображения
Тип файла: jpg Безымянный.jpg (13.8 Кб, 450 просмотров)
darek13 вне форума Ответить с цитированием
Старый 15.06.2011, 15:00   #10
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> то что я использую готовое, не засчитают надо свой алгоритм что бы был

сейчас вы используете Crypt API от майкрософт, вашего там 1% (не работающий )
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шифрование AES Samara Помощь студентам 3 29.10.2011 18:10
Известный компьютерщик.Немогу распознать bondik Свободное общение 3 26.02.2011 22:12
Шифрование AES SergunchikSK Общие вопросы Delphi 13 25.08.2009 10:36
Шифрование алгоритмом RC4 Alexteks Общие вопросы Delphi 0 05.05.2009 09:41