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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 18.12.2010, 22:10   #1
lnikon
 
Регистрация: 22.07.2010
Сообщений: 6
По умолчанию Вопрос по шифрованию

Помогите пожалуйста, есть библиотека wcrypt2 и вот такой код

Код:
Код:
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls;

type
  TfrmMain = class(TForm)
    btnEcnrypt: TButton;
    edtText: TEdit;
    edtKey: TEdit;
    lbText: TLabel;
    lbKey: TLabel;
    btnDecrypt: TButton;
    procedure btnEcnryptClick(Sender: TObject);
    procedure btnDecryptClick(Sender: TObject);
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

uses
  Wcrypt2;

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();

Последний раз редактировалось Stilet; 19.12.2010 в 11:43.
lnikon вне форума Ответить с цитированием
Старый 18.12.2010, 22:10   #2
lnikon
 
Регистрация: 22.07.2010
Сообщений: 6
По умолчанию

Код:
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;
procedure TfrmMain.btnEcnryptClick(Sender: TObject);
var
  f: TextFile;
  cipherText: AnsiString;
begin
  cipherText := 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(AnsiString(chars), edtKey.Text);
  MessageBox(Handle, 'Readed from ciphertext.txt.', 'Done.', MB_OK);
end;

end.
Зашифровываться зашифровывается, а вот на расшифровываться говорит:
Сообщение: System error. Code -2146893819. Плохие данные
В отладчике: [DCC Warning] uMain.pas(212): W1057 Implicit string cast from 'AnsiString' to 'string'

Последний раз редактировалось Stilet; 19.12.2010 в 11:43.
lnikon вне форума Ответить с цитированием
Старый 19.12.2010, 04:29   #3
lnikon
 
Регистрация: 22.07.2010
Сообщений: 6
По умолчанию Исходники

Вот исходники, скомпилированный пример, работает, а вот если я собираю даже заново исходники (у меня codegear rad studio 2009), то на расшифровке он выдает ошибку
Вложения
Тип файла: rar delphi.rar (258.5 Кб, 27 просмотров)
lnikon вне форума Ответить с цитированием
Старый 19.12.2010, 11:48   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

У мя Делфи6 так что проверить не могу, но скажу что скорее всего тебе нужно переписать
Код:
procedure TfrmMain.btnDecryptClick(Sender: TObject);
....
 
  edtText.Text := decrypt(String(chars), edtKey.Text);
end;
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 19.12.2010, 14:03   #5
lnikon
 
Регистрация: 22.07.2010
Сообщений: 6
По умолчанию

Нет, не помогло, а в 6-ой дельфи норм все? я вот думаю мож скачать 7-ой и на нем попробовать
lnikon вне форума Ответить с цитированием
Старый 19.12.2010, 15:47   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
а в 6-ой дельфи норм все?
Да вроде работает. 2010 с собой нет увы. Удалил ее, поскольку проблемы схожие с твоей меня достали.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 19.12.2010, 17:51   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Забыли:

Код:
procedure TfrmMain.btnDecryptClick(Sender: TObject);
var
  f: file of Char;
  chars: array of Char;
  cbChars: Integer;
begin
заменить на:

Код:
procedure TfrmMain.btnDecryptClick(Sender: TObject);
var
  f: file of AnsiChar;
  chars: array of AnsiChar;
  cbChars: Integer;
begin
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 19.12.2010, 17:57   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Вообще, результат шифрования - это массив байтов. Записывать его через текстовый файл - не слишком удачная идея. Лучше используйте TStream (как для записи, так и для чтения). TFileStream или даже просто TMemoryStream.

Аналогично, AnsiString - не очень подходящий контейнер для шифрованного текста. Наилучший вариант - массив байт или, снова, TStream. На крайний случай - RawByteString (в D2007 и ниже - AnsiString).
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача по шифрованию Verwolf Помощь студентам 1 23.10.2010 14:03
Написать 2 задачи по шифрованию Yaga Фриланс 19 11.01.2009 21:38
дипломная работа по шифрованию Gulnaz Помощь студентам 1 13.11.2008 14:03
Вопрос наверное про функции, а так точно даже не знаю про что. (Вопрос начинющего #6) Albert2008 Общие вопросы Delphi 4 21.08.2008 15:33
вопрос по сокетам и общение как в ICQ.Сложный вопрос... Руслантус Общие вопросы C/C++ 2 12.08.2008 21:10