Обфускация части полей в БД

7 views
Skip to first unread message

Naim Sh.

unread,
May 23, 2018, 3:33:34 AM5/23/18
to moscow-mysq...@googlegroups.com
Коллеги, наверняка вы сталкивались с этой задачей и можете подсказать как её решать ?

Нужно часть полей(типа email , номер телефона) обфусцировать { это нужно,чтобы разрабы с этой
копией бд( она прилетает с мастера ) могли работать и не видели части конфиденциальной инфы } .

Решение в лоб , типа брать и на скопируемой базе делать update не очень хочется , ибо это чревато,
периодической нагрузкой на бд .

Павел Добряков

unread,
May 23, 2018, 4:36:41 AM5/23/18
to moscow-mysq...@googlegroups.com
View же


--

---
Вы получили это сообщение, поскольку подписаны на группу Moscow MySQL User Group.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес moscow-mysql-user-group+unsub...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/d/optout.

Naim Sh.

unread,
May 23, 2018, 4:41:33 AM5/23/18
to moscow-mysq...@googlegroups.com
Можешь пример скинуть, просто эти поля тоже нужно мусором заполнять( как я понимаю статическим) и
им отдавать ?
И как оно при нагрузки ?

Roman V. Nikolaev

unread,
May 23, 2018, 4:50:47 AM5/23/18
to moscow-mysq...@googlegroups.com
Если хочется шифрования то все относительно просто:
1. Сохраняешь в БД в зашифрованном виде. Достаешь - расшифровываешь.
2. На боевом в конфиге будет правильный ключ шифрования, на тестовом
другой ключ - позволит нормально работать на тестовом, но расшифровать
боевые данные не позволит.
3. Использовать для шифрования можно что-то вида https://hashids.org/
или еще что-нибудь похожее. Сейчас во фреймворках как правило есть
какой-либо встроенный механизм шифрования/подписи, для кук например.

--
Roman V. Nikolaev

Roman V. Nikolaev

unread,
May 23, 2018, 4:54:13 AM5/23/18
to moscow-mysq...@googlegroups.com
hashids правда только для чисел. Что-то посоветовать для почты и т.д.
незная на чем вы пишите софт я не могу =)

--
Roman V. Nikolaev

Naim Sh.

unread,
May 23, 2018, 4:56:21 AM5/23/18
to moscow-mysq...@googlegroups.com
PHP

Roman V. Nikolaev

unread,
May 23, 2018, 5:54:42 AM5/23/18
to moscow-mysq...@googlegroups.com
On 23.05.2018 11:56, Naim Sh. wrote:
> PHP

Для PHP подсказать не могу. Что-то похожее на правду есть в этом треде

https://stackoverflow.com/questions/16600708/how-do-you-encrypt-and-decrypt-a-php-string

Например:

$string_to_encrypt="Test";
$password="password";
$encrypted_string=openssl_encrypt($string_to_encrypt,"AES-128-ECB",$password);
$decrypted_string=openssl_decrypt($encrypted_string,"AES-128-ECB",$password)

--
Roman V. Nikolaev

Naim Sh.

unread,
May 23, 2018, 8:06:58 AM5/23/18
to moscow-mysq...@googlegroups.com
Лучше вариант который - просто поменять название таблиц на view . чем накручивать новую логику
разрабам .
вопрос как лучше view написать и что там лучше использовать чтобы если даже значение в поле phone
есть все равно отдавать 0 ?

Павел Добряков

unread,
May 23, 2018, 9:59:45 AM5/23/18
to moscow-mysq...@googlegroups.com
md5

Naim Sh.

unread,
May 23, 2018, 10:03:16 AM5/23/18
to moscow-mysq...@googlegroups.com
А как оно будет при highload на сколько приблизительно в % будет просадка в CPU и по памяти ?

Павел Добряков

unread,
May 23, 2018, 10:04:21 AM5/23/18
to moscow-mysq...@googlegroups.com
Погоди, какой Highload  - это же просто для разработчиков ?

Alexey Kopytov

unread,
May 23, 2018, 10:15:09 AM5/23/18
to moscow-mysq...@googlegroups.com
On Wed, 23 May 2018 16:59:23 +0300, Павел Добряков wrote:

> md5

Или вообще REPEAT('*', CHAR_LENGTH(phone))

naim

unread,
May 23, 2018, 12:17:00 PM5/23/18
to moscow-mysq...@googlegroups.com
Это просто оценить нагрузку, насколько будущее решение лучше чем сейчас скрипт который периодически делает update user set phone='' where phone !=''

Pavel

unread,
May 23, 2018, 12:23:51 PM5/23/18
to moscow-mysq...@googlegroups.com
Repeat хорошо пока разработчики не захотят тестировать производительность запросов по подобным полям . А тут распределение индекса будет совсем веселым )

> 23 мая 2018 г., в 17:15, Alexey Kopytov <akop...@gmail.com> написал(а):
>
>> On Wed, 23 May 2018 16:59:23 +0300, Павел Добряков wrote:
>>
>> md5
>
> Или вообще REPEAT('*', CHAR_LENGTH(phone))
>
> --
>
> --- Вы получили это сообщение, поскольку подписаны на группу Moscow MySQL User Group.
>
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес moscow-mysql-user...@googlegroups.com.

Chernomorets Sergey

unread,
May 24, 2018, 1:56:49 AM5/24/18
to Moscow MySQL User Group
Можно перелить данные в соседнюю таблицу с заменой телефона на лету - это должно быть побыстрее. Заливать пачками по несколько тысяч строк (или транзакцию коммитить). Потом старую таблицу заменить на новую.

У нас каждую ночь с бекапного сервера заливается файловая копия, запускается mysql с увеличенным innodb_log_file_size (можно и другие параметры подкрутить), обфусцируются нужные таблицы в несколько потоков (список таблиц предварительно отсортирован по размеру), затем innodb_log_file_size уменьшаем путем перезапуска mysql, делаем от этих данных несколько снепшотов средствами LVM и на каждом снепшоте запускаем свой инстанс mysql. Все это живет полностью на самсунговских SSD EVO 850. Пару лет назад базовая копия лежала на SSD, снепшоты - на 10Krpm hdd. 

среда, 23 мая 2018 г., 10:33:34 UTC+3 пользователь naim написал:

Петр Щучкин

unread,
May 24, 2018, 3:01:57 AM5/24/18
to Moscow MySQL User Group
Опишу чуть подробнее.

Скрипт на php генерирует запросы в виде последовательности
CREATE TABLE b LIKE a;
DROP INDEX 1, .... (удаляются индексы)
INSERT INTO b SELECT (... вот тут как раз делается обфускация некоторых полей на лету ...) FROM a WHERE exclude;
ALTER TABLE b ADD INDEX 1, ...., ALGORITHM=inplace (добавляются индексы)
RENAME b TO a, a TO old;
DROP old;


Это работает быстрее чем UPDATE - проверено, особенно если затюнить сервер как Сергей писал выше.

Такие последовательности записываются для каждой таблицы в отдельный файл, затем запускаются параллельно.

Объем обфусцируемых данных примерно 60 Гб.

Вот примерно так выглядит обфускация поля телефона

// Замена телефона
// Сначала заменяем 6 цифр в конце длинных последовательностей
// Если замена ни к чему не привела, заменяем по маске -NN-NN
// Если и эта замена ни к чему не привела,
// то тупо заменяем все последовательности из двух цифр на случайную последовательность из двух цифр
// (получаются повторения, но это редко)
$fun_replace_phone = function ($field_name) {
return "IF(
(@phone_obs:=REGEXP_REPLACE($field_name, '([0-9]*)[0-9]{6}', CONCAT(\"\\\\1\", RPAD(@random := CEIL(RAND()*1000000), 6, @random))))
= $field_name,
IF(
(@phone_obs2:=REGEXP_REPLACE($field_name, '([^0-9]+)[0-9]{2}([^0-9]+)[0-9]{2}', CONCAT(\"\\\\1\", SUBSTR(@random, 1, 2), \"\\\\2\", SUBSTR(@random, 3, 2)))) = $field_name,
REGEXP_REPLACE($field_name, '[0-9]{2}', SUBSTR(@random, 1, 2)),
@phone_obs2
),
@phone_obs)";

};



В замене email AES_ENCRYPT лишний, сначала хотели сделать чтобы можно было расшифровать, но потом оказалось что слишком длинные email создают неудобства и пришлось обрезать. При этом обфусцируется толька часть, которая слева от @, домен остаётся.

// Замена email
$fun_replace_email = function ($field_name) use ($secret) {
return "CONCAT(
SUBSTR(LOWER(SHA1(HEX(AES_ENCRYPT(SUBSTRING_INDEX($field_name, '@', 1), '$secret')))), 1 , 15),
'@',
SUBSTRING_INDEX($field_name, '@', -1)
)";
};




четверг, 24 мая 2018 г., 8:56:49 UTC+3 пользователь Chernomorets Sergey написал:
Reply all
Reply to author
Forward
0 new messages