openssl_encrypt поиск подстроки

Тема в разделе "PHP", создана пользователем LEXAlForpostl, 8 дек 2017.

Модераторы: latteo
  1. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    750
    Симпатии:
    227
    Здравствуйте.
    Данные закодированы openssl_encrypt (AES-256-CBC). Необходимо организовать поиск подстроки.
    Если подстрока А входит в строку В, то и openssl_encrypt(A) будет входить в строку openssl_encrypt(В?
    Разумеется все параметры для openssl_encrypt в обоих случаях идентичны.

    UPD.
    Key, Vector - постоянные значения.
    Закодировал
    A
    AB
    ABC
    Получил
    11111abcdef
    11111qwertyplopolpollpollpol
    11111qwertyujikouuokghjoukoukglhjkghojuoyjkghghj

    P.S.
    Разумеется закодированные строки были совсем другие и ответы на них. Но суть надеюсь передал. Вопрос, подскажите, пожалуйста, алгоритм из open_ssl'я, который бы кодировал без "хвостов". Чтоб затем можно было организовать поиск подстроки без проблем. Спасибо!
     
    Последнее редактирование: 8 дек 2017
  2. v1rus74

    v1rus74

    Moderator
    Регистр.:
    2 авг 2016
    Сообщения:
    75
    Симпатии:
    91
    Два варианта:
    1. Использовать любой потоковый шифр (RC4, ChaCha20);
    2. Использовать любой блочный шифр в одном из режимов шифрования, которые, по сути, превращают блочный шифр в потоковый (CFB, OFB, CTR). Я рекомендую режим CTR как самый производительный и поддающийся параллелизации. Например, AES-256-CTR.

    Обратите внимание, что по умолчанию функция openssl_encrypt() возвращает значение, кодированное в base64. Для ваших целей нужна сырая строка, поэтому нужно передать опцию OPENSSL_RAW_DATA.

    Если нужно визуально проконтролировать результаты, то сырую строку можно преобразовать в hex функцией bin2hex().

    Вот тестовый сниппет:
    PHP:
    $result openssl_encrypt($data'AES-256-CTR'$key,  OPENSSL_RAW_DATA$iv);
    echo 
    bin2hex($result);
     
    latteo и LEXAlForpostl нравится это.
  3. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    750
    Симпатии:
    227
    Спасибо то, что доктор прописал.
    Единственный вопрос. Как порекомендуете хранить в БД, в сыром виде или в 16-теричном?
     
  4. v1rus74

    v1rus74

    Moderator
    Регистр.:
    2 авг 2016
    Сообщения:
    75
    Симпатии:
    91
    Лучше хранить в сыром виде (TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, смотря какая максимальная длина строки ожидается). Занимает в 2 раза меньше места на диске и обрабатывается до 2 раз быстрее, чем текстовая hex-строка. Но есть 1 минус: с такими данными неудобно работать вручную через консоль, Adminer и т.д. Но можно, используя MySQL-функции HEX() и UNHEX().
     
    Последнее редактирование: 9 дек 2017
  5. BaBL

    BaBL

    Регистр.:
    13 ноя 2012
    Сообщения:
    165
    Симпатии:
    108
    У меня когда-то была подобная задача и могу сказать что так ты ее не решишь.

    Ты проверил вхождения:
    A
    AB
    ABC

    А проверь теперь такие:
    BA
    BAC
    BCA
    CAB

    найдется ли у тебя А во всех? А при использовании B разной длинны?

    Если ты собираешься делать поиск вхождений - придется либо использовать что-то совсем простое вроде шифра Цезаря (обычное замещение/подстановка), либо хранить данные в отркытом виде.

    Опять же, не очень понятна задача на самом деле.
     
  6. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    750
    Симпатии:
    227
    Задачу описал четко))
    Меня интересуют первые 150-200 символов. Если они одинаковые - тогда это считается дублем. Это раз.
    Во вторых, что Вам мешает в последовательности ВА найти А. Не вижу проблем. (Или я чего-то не понял).

    Планировал под это дело взять varchar[4000] и сделать ключ по первым 200 символам, или не правильно?
     
  7. v1rus74

    v1rus74

    Moderator
    Регистр.:
    2 авг 2016
    Сообщения:
    75
    Симпатии:
    91
    Здесь имеется в виду вероятность коллизии, которой можно пренебречь только при достаточно большой длине подстроки А. К примеру, если подстрока A кодируется как 0xF734 и подстрока B окажется достаточно большой, то эти 2 байта реально могут встретиться в подстроке B. У вас длина подстроки A 150-200 символов, поэтому можно забить, но только если приложение не mission critical.
    В таком виде неправильно. Тогда уж VARBINARY(4000). А вот что лучше, VARBINARY или BLOB, это вам лучше спросить в профильной ветке, я в реляционных СУБД не силён.