Шифрование данных

Обсуждение возникших проблем, предложений и ошибок IBDAC компонентов
Закрыто
raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Шифрование данных

Сообщение raMZES » Пт 13 июл 2012 22:03

Добрый вечер. Подскажите пожалуйста ответы на несколько вопросов. Крутятся в голове и все.
Сегодня на работе попробовал новую версию IBDac - 4.2.7 с нужной мне функцией шифрования данных. Прочитал справку с примером шифрования, также нашел топик, где человек просит объяснить, как работает шифрование данных (http://forums.devart.com/viewtopic.php?f=28&t=24452). Там есть код (хотя он и относится к UniDac, я думаю, что в IBDac будет тоже самое):

Код: Выделить всё

UniQuery.SQL.Text := 'SELECT * FROM EMP';

UniQuery.Encryption.Encryptor := UniEncryptor;
UniQuery.Encryption.Fields := 'ENAME, SAL, FOTO';
UniEncryptor.Password := '11111';

UniQuery.DataTypeMap.AddFieldNameRule ('ENAME', ftString);
UniQuery.DataTypeMap.AddFieldNameRule ('SAL', ftFloat);

UniQuery.Open;
В справке компонент написано:
TCREncryptor supports encryption of string or binary fields only (ftString, ftWideString, ftBytes, ftVarBytes, ftBlob, ftMemo, ftWideMemo).
--
Therefore, to have the possibility to encrypt other data types (such as date, number, etc.), it is necessary to create a field of the binary or BLOB type in the table, and then convert it into the desired type on the client side with the help of data mapping.


Т.е. TCREncryptor поддерживает шифрование для строковых либо двоичных полей. Для остальных используйте Data Type Mapping.
1. Подскажите пожалуйста, обязательно ли использовать Data Type Mapping, как написано в коде:

Код: Выделить всё

...
ENAME VARCHAR(2000) CHARACTER SET OCTETS COLLATE OCTETS
...

Код: Выделить всё

...
UniQuery.DataTypeMap.AddFieldNameRule ('ENAME', ftString);
...
для строковых полей?

2. CHARACTER SET OCTETS COLLATE OCTETS указаны просто для того, чтобы сервер не делал никаких преобразований или есть какой-либо другой смысл использования этой кодировки и порядка сортировки?

3. Процедура SetKey. Из справки:
Use SetKey to set a key, using which data is encrypted.
Эта процедура необходима для смены пароля? Можно ли просто при IBQuery.BeforeOpen написать как в примере:

Код: Выделить всё

UniEncryptor.Password := 'мой пароль';
?

4. TCRInvalidHashAction. Из справки:
ihFail: The EInvalidHash exception is raised and further data reading from the server is interrupted.
ihIgnoreError: In spite of the fact that the data is not valid, the value is set in the field. No exception is raised.
ihSkipData: The value of the field for this record is set to Null. No exception is raised.
.
То есть, это метод обработки ошибок, когда, как написано, hash data is invalid.
Я попробовал записать данные (с ehTagAndHash) с алгоритмом eaAES128 (свойство InvalidHashAction установил в ihIgnoreError), затем поменял алгоритм на eaBlowfish, перекомпилировал приложение, и при открытии запроса "вылетают" ошибки. Так должно быть?

Заранее благодарен за ответы.

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Шифрование данных

Сообщение AndreyZ » Пн 16 июл 2012 16:03

Здравствуйте,

1. IBDAC для VARCHAR полей с чарсетом OCTETS создает TVarBytesField поля. Для удобства работы с такими полями (используя визуальные компоненты), Вам следует задавать для таких полей соответствие типу TStringField.
2. Да, Вы правы, CHARACTER SET OCTETS COLLATE OCTETS используется для того чтобы сервер не делал никаких преобразований и для увеличения производительности шифрования.
3. Использование метода SetKey и свойства Password взаимоисключающе. Для шифрования необходим ключ которым шифруются данные. Есть два способа задать его:
- напрямую указать его методом SetKey;
- установкой свойства Password. При этом IBDAC генерирует ключ на основе значения свойства Password.
4. Это корректное поведение. IBDAC сравнивает хэш данных сохраненный в поле на сервере с хэшем который высчитывается на клиенте используя зашифрованные данные. Если на момент чтения данных с сервера IBDAC определяет что данные некорректны и он не может даже расшифровать данные, генерируется исключение EInvalidEncData.

raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Re: Шифрование данных

Сообщение raMZES » Пн 16 июл 2012 17:47

Спасибо за ответы.
Но все же не пойму по поводу п.4. Вы доступно написали, что:
IBDAC сравнивает хэш данных сохраненный в поле на сервере с хэшем который высчитывается на клиенте используя зашифрованные данные. Если на момент чтения данных с сервера IBDAC определяет что данные некорректны и он не может даже расшифровать данные, генерируется исключение EInvalidEncData.
.
Исключение EInvalidEncData генерируется в любом случае, если на момент чтения данных с сервера IBDAC определяет что данные некорректны и он не может даже расшифровать данные?
Независимо, от того, как установлено свойство TCRInvalidHashAction - в ihFail, ihIgnoreError либо ihSkipData?
Не подскажите, как перехватить такое исключение?
Код:

Код: Выделить всё

procedure TMyForm.OpenConClick(Sender: TObject);
begin
  if not TestConn.Connected then
    try
      TestConn.Connect;
      TestQuery.Open;
    except
      on e: EIBCError do
      begin
        if (e is EInvalidEncData) then
          Application.MessageBox('Невозможно расшифровать данные.', 'Ошибка',
            MB_OK + MB_ICONSTOP + MB_TOPMOST)
        else
          Application.MessageBox('Другая ошибка...', 'Ошибка',
            MB_OK + MB_ICONSTOP + MB_TOPMOST);
      end;
    end;
end;
к сожалению (и естественно) не компилируется.
Спасибо.

ZEuS
Devart Team
Сообщения: 11
Зарегистрирован: Пт 06 апр 2012 06:10

Re: Шифрование данных

Сообщение ZEuS » Вт 17 июл 2012 08:55

Да, исключение EInvalidEncData генерируется в том случае, если IBDAC не может расшифровать данные вообще (например, если в свойстве TIBCEncryptor.EncryptionAlgorithm установлен алгоритм шифрования, отличный от алгоритма, которым данные были зашифрованы). Свойство InvalidHashAction будет использовано уже в том случае, если IBDAC успешно расшифровал данные и высчитал хеш, но он не соответствует хешу, сохраненному в поле на сервере.
Для правильного перехвата исключения EInvalidEncData нужно изменить блок "except ... end" в приведенном примере следующим образом:

Код: Выделить всё

except
  on e: EInvalidEncData do
    Application.MessageBox('Невозможно расшифровать данные.', 'Ошибка',
      MB_OK + MB_ICONSTOP + MB_TOPMOST)
  else
    Application.MessageBox(PChar('Другая ошибка... '), 'Ошибка',
      MB_OK + MB_ICONSTOP + MB_TOPMOST);
end;
Исключение EInvalidEncData не является наследником EIBCError, т.к. не относится к исключительным ситуациям сервера Interbase/Firebird, а возникает при ошибках шифрования. Поэтому, на стадии компиляции возникает ошибка.

raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Re: Шифрование данных

Сообщение raMZES » Вт 17 июл 2012 15:08

Всё понял. Спасибо.

raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Re: Шифрование данных

Сообщение raMZES » Чт 19 июл 2012 14:24

Здравствуйте еще раз. Помогите пожалуйста разобраться с шифрованием при использовании хранимых процедур.

Есть таблица для хранения данных:

Код: Выделить всё

CREATE TABLE PASSW (
    IDPASS       TINTEGNUM NOT NULL /* TINTEGNUM = INTEGER */,
    READ_PASS    TPASSWORD /* TPASSWORD = VARCHAR(100) */,
    WRITE_PASS   TPASSWORD /* TPASSWORD = VARCHAR(100) */,
    ADV_PASS_ON  TTARIF /* TTARIF = VARCHAR(25) */,
    ADV_PASS     TPASSWORD /* TPASSWORD = VARCHAR(100) */
);
Есть процедура, которая модифицирует\вставляет данные в таблице:

Код: Выделить всё

create or alter procedure PASSW_IU (
    IDPASS integer,
    READ_PASS TPASSWORD,
    WRITE_PASS TPASSWORD,
    ADV_PASS_ON varchar(25),
    ADV_PASS TPASSWORD)
as
begin
  if (exists(select IDPASS
             from PASSW
             where (IDPASS = :IDPASS))) then
    update PASSW
    set IDPASS = :IDPASS,
        READ_PASS = :READ_PASS,
        WRITE_PASS = :WRITE_PASS,
        ADV_PASS_ON = :ADV_PASS_ON,
        ADV_PASS = :ADV_PASS
    where (IDPASS = :IDPASS);
  else
    insert into PASSW (IDPASS, READ_PASS, WRITE_PASS, ADV_PASS_ON, ADV_PASS)
    values (:IDPASS, :READ_PASS, :WRITE_PASS, :ADV_PASS_ON, :ADV_PASS);
end
Пишу код:

Код: Выделить всё

...    
    // -------------------------------------------------------------
    // Выбираем процедуру...
    // -------------------------------------------------------------
    DM.WorkHorseSP.Active := false;
    DM.WorkHorseSP.StoredProcName := 'PASSW_IU';
    // ----------------------------------------------------------
    // Подготавливаем
    // ----------------------------------------------------------
    DM.WorkHorseSP.Prepare;
    // -------------------------------------------------------------
    // Присваиваем параметры
    // -------------------------------------------------------------
    DM.WorkHorseSP.Params.ParamByName('IDPASS').AsInteger :=
      DM.QMainIDMAIN.AsInteger;

    DM.WorkHorseSP.Params.ParamByName('WRITE_PASS').Value := Trim
      (edtWritePass.Text); //поле ввода
...
    // -------------------------------------------------------------
    // Шифруем
    // -------------------------------------------------------------
    DM.WorkHorseSP.Encryption.Encryptor := DM.Encryptor;
    DM.WorkHorseSP.Encryption.Fields := 'READ_PASS, WRITE_PASS, ADV_PASS';
    DM.WorkHorseSP.DataTypeMap.AddFieldNameRule('READ_PASS', ftString);
    DM.WorkHorseSP.DataTypeMap.AddFieldNameRule('WRITE_PASS', ftString);
    DM.WorkHorseSP.DataTypeMap.AddFieldNameRule('ADV_PASS', ftString);
    DM.Encryptor.Password := '123';
    // --------------------------------------------------------------
    // Пытаемся выполнить и закомитить
    // --------------------------------------------------------------
    DM.WorkHorseSP.ExecProc;
    if DM.WriteTr.Active then
      DM.WriteTr.Commit;
Данные записываются, но они не зашифрованные.

raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Re: Шифрование данных

Сообщение raMZES » Пн 23 июл 2012 05:59

Кто-нибудь подскажет как решить?

ZEuS
Devart Team
Сообщения: 11
Зарегистрирован: Пт 06 апр 2012 06:10

Re: Шифрование данных

Сообщение ZEuS » Пн 23 июл 2012 16:17

На данный момент шифрование параметров не реализовано из-за возможных неоднозначностей при расшифровке OUT-параметров.
Мы исследуем возможность реализации данной функциональности в одной из следующих версий IBDAC.

raMZES
Сообщения: 30
Зарегистрирован: Ср 14 сен 2011 10:49

Re: Шифрование данных

Сообщение raMZES » Вт 31 июл 2012 12:30

Добрый день. Подскажите, будет ли реализована данная функциональность в одном из следующих версий IBDAC? В билде 4.2.8 24-Jul-12 об этом ни слова.

ZEuS
Devart Team
Сообщения: 11
Зарегистрирован: Пт 06 апр 2012 06:10

Re: Шифрование данных

Сообщение ZEuS » Пт 03 авг 2012 08:53

Мы планируем реализовать данную функциональность в одной из следующих версий IBDAC. Как только она будет реализована, соответствующая информация будет добавлена в History.

Закрыто