почему нельзя расшифровать md5

Риски и проблемы хеширования паролей

Безопасность всегда была неоднозначной темой, провоцирующей многочисленные горячие споры. И всё благодаря обилию самых разных точек зрения и «идеальных решений», которые устраивают одних и совершенно не подходят другим. Я считаю, что взлом системы безопасности приложения всего лишь вопрос времени. Из-за быстрого роста вычислительных мощностей и увеличения сложности безопасные сегодня приложения перестанут завтра быть таковыми.

Недостатки простого хэширования

Тот факт, что с помощью эффективного алгоритма невозможно провести операцию, обратную хэшированию, и восстановить исходные данные, не означает, что вас не могут взломать. Если хорошо поискать, то можно найти базы данных с хэшами распространённых слов и коротких фраз. Кроме того, простые пароли можно быстро и легко брутфорсить или взламывать перебором по словарю.

Вот небольшая демонстрация, как инструмент sqlmap через внедрение SQL-кода взламывает пароли с помощью брутфорса хэшей, сгенерированных алгоритмом MD5.

Почему небезопасны хэши с применением соли

Чтобы затруднить атаки описанного вида, применяется так называемая соль. Это стандартное средство, но в условиях современных вычислительных мощностей его уже недостаточно, особенно если длина соли невелика.

В общем виде функцию с использованием соли можно представить так:

f(password, salt) = hash(password + salt)

Для затруднения брутфорс-атаки соль должна быть длиной не менее 64 символов. Но проблема в том, что для дальнейшей аутентификации пользователей соль должна храниться в БД в виде простого текста.

if (hash([введённый пароль] + [соль]) == [хэш]) тогда пользователь аутентифицирован

Благодаря уникальности соли для каждого пользователя мы можем решить проблему коллизий простых хэшей. Теперь все хэши будут разными. Также уже не сработают подходы с гугленьем хэшей и брутфорсом. Но если злоумышленник через внедрение SQL-кода получит доступ к соли или БД, то сможет успешно атаковать брутфорсом или перебором по словарю, особенно если пользователи выбирают распространённые пароли (а-ля 123456).

Тем не менее взлом любого из паролей уже не позволит автоматически вычислить пользователей, у которых тот же пароль, — ведь у нас ВСЕ хэши разные.

Момент случайности

Для генерирования подходящей соли нам нужен хороший генератор случайных чисел. Сразу забудьте о функции rand().

Есть замечательная статья, посвящённая этому вопросу. Вкратце: компьютер сам по себе не генерирует случайные данные, это детерминированная машина. То есть каждый выполняемый алгоритм, получив несколько раз на входе одни и те же данные, на выходе представит один и тот же результат.

Когда от компьютера хотят случайное число, то обычно он берёт данные из нескольких источников (например, переменные среды: дату, время, количество записанных/считанных байтов и т. д.), а затем производит над ними вычисления для получения «случайных» данных. Поэтому такие данные называют псевдослучайными. А значит, если каким-то образом воссоздать набор исходных состояний на момент исполнения псевдослучайной функции, то мы сможем сгенерировать то же самое число.

Если псевдослучайный генератор ещё и реализован неправильно, то в генерируемых им данных можно обнаружить паттерны, а с их помощью предсказать результат генерирования. Взгляните на эту картинку, представляющую собой результат работы PHP-функции rand():

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

А теперь сравните с данными, сгенерированными полноценным генератором случайных чисел:

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

К сожалению, ни rand(), ни mt_rand() нельзя считать подходящими инструментами для обеспечения высокого уровня безопасности.

Если вам нужно получить случайные данные, воспользуйтесь функцией openssl_random_pseudo_bytes(), которая доступна начиная с версии 5.3.0. У неё даже есть флаг crypto_strong, который сообщит о достаточном уровне безопасности.

Растяжение пароля

Можно внедрить растяжение пароля, это позволяет ещё больше затруднить брутфорс-атаки. Растяжение представляет собой итеративный, или рекурсивный, алгоритм, который раз за разом вычисляет хэш самого себя, десятки тысяч раз (а то и более).

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Количество итераций должно быть таково, чтобы общее время вычислений заняло как минимум одну секунду. Чем более длительное получается хэширование, тем больше времени атакующему приходится тратить на взлом.

Для растяжения пароля можно использовать стандартные алгоритмы, например PBDKDF2, представляющий собой функцию формирования ключа:

Есть и более затратные по времени и памяти алгоритмы, например bcrypt (о нём мы поговорим ниже) или scrypt:

На данный момент в PHP не реализована поддержка алгоритма scrypt, но можно воспользоваться реализацией от Domblack.

Применение технологий шифрования

Многие путаются в терминах «хэширование» и «шифрование». Как было упомянуто выше, хэш — результат работы псевдослучайной функции, в то время как шифрование — осуществление псевдослучайного преобразования: входные данные делятся на части и обрабатываются таким образом, что результат становится неотличим от результата работы полноценного генератора случайных чисел. Однако в этом случае можно провести обратное преобразование и восстановить исходные данные. Преобразование осуществляется с помощью криптоключа, без которого невозможно провести обратное преобразование.

Есть и ещё одно важное отличие шифрования от хэширования: размер пространства выходного сообщения не ограничен и зависит от размера входных данных в соотношении 1:1. Поэтому нет риска возникновения коллизий.

Необходимо уделять большое внимание правильности использования шифрования. Не думайте, что для защиты важных данных достаточно просто зашифровать по какому-нибудь алгоритму. Есть немало способов украсть данные. Главное правило — никогда не занимайтесь самодеятельностью и пользуйтесь уже готовыми, отработанными реализациями.

Некоторое время назад у Adobe была мощная утечка пользовательской БД из-за неправильно реализованного шифрования. Давайте разберём, что у них произошло.

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Предположим, что в таблице хранятся следующие данные в виде обычного текста:

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Мы не знаем, какой применялся криптоключ. Но если проанализировать данные, то можно заметить, что в строках 2 и 7 используется один и тот же пароль, так же как и в строках 3 и 6.

Пришло время обратиться к подсказке пароля. В строке 6 это «I’m one!», что совершенно неинформативно. Зато благодаря строке 3 мы можем предположить, что пароль — queen. Строки 2 и 7 по отдельности не позволяют вычислить пароль, но если проанализировать их вместе, то можно предположить, что это halloween.

Ради снижения риска утечки данных лучше использовать разные способы хэширования. А если вам нужно шифровать пароли, то обратите внимание на настраиваемое шифрование:

Пусть у нас есть тысячи пользователей и мы хотим зашифровать все пароли. Как было показано выше, лучше избегать использования единого криптоключа. Но и сделать для каждого пользователя уникальный ключ мы тоже не можем, поскольку хранение ключей само по себе превратится в проблему. В этом случае достаточно применять общий для всех криптоключ, но при этом делать «настройку», уникальную для каждого пользователя. Комбинация ключа и «настройки» и будет являться уникальным ключом для каждого пользователя.

Простейший вариант «настройки» — так называемый первичный ключ, уникальный для каждой записи в таблице. Не рекомендуется пользоваться им в жизни, здесь он показан лишь для примера:

f(key, primaryKey) = key + primaryKey

Здесь ключ и первичный ключ просто сцепляются вместе. Но для обеспечения безопасности следует применить к ним алгоритм хэширования или функцию формирования ключа (key derivation function). Также вместо первичного ключа можно для каждой записи использовать одноразовый ключ (аналог соли).

Если мы применим к нашей таблице настраиваемое шифрование, то она будет выглядеть так:

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Конечно, нужно будет ещё что-то сделать с подсказками паролей, но всё-таки уже получилось хоть что-то адекватное.

Обратите внимание, что шифрование — не идеальное решение для хранения паролей. В связи с угрозами внедрения кода лучше избегать этого метода защиты. Для хранения паролей надежнее всего использовать алгоритм bcrypt. Но нельзя забывать и о том, что даже самые лучшие и проверенные решения обладают уязвимостями.

PHP 5.5

Сегодня оптимальным способом хэширования паролей считается использование bcrypt. Но многие разработчики всё ещё предпочитают старые и более слабые алгоритмы вроде MD5 и SHA-1. А некоторые при хэшировании даже не пользуются солью. В PHP 5.5 был представлен новый API для хэширования, который не только поощряет применение bcrypt, но и существенно облегчает работу с ним. Давайте разберём основы использования этого нового API.

password_hash()

Несмотря на высокий уровень безопасности, обеспечиваемый функцией crypt(), многие считают её слишком сложной, из-за чего программисты часто допускают ошибки. Вместо неё некоторые разработчики используют для генерирования хэшей комбинации слабых алгоритмов и слабых солей:

Функция password_hash() существенно облегчает разработчику жизнь и повышает безопасность кода. Для хэширования пароля достаточно скормить его функции, и она вернёт хэш, который можно поместить в БД:

И всё! Первый аргумент — пароль в виде строки, второй аргумент задаёт алгоритм генерирования хэша. По умолчанию используется bcrypt, но при необходимости можно добавить и более сильный алгоритм, который позволит генерировать строки большей длины. Если в своём проекте вы используете PASSWORD_DEFAULT, то удостоверьтесь, что ширина колонки для хранения хэшей не менее 60 символов. Лучше сразу задать 255 знаков. В качестве второго аргумента можно использовать PASSWORD_BCRYPT. В этом случае хэш всегда будет длиной в 60 символов.

Обратите внимание, что вам не нужно задавать значение соли или стоимостного параметра. Новый API всё сделает за вас. Поскольку соль является частью хэша, то вам не придётся хранить её отдельно. Если вам всё-таки нужно задать своё значение соли (или стоимости), то это можно сделать с помощью третьего аргумента:

Всё это позволит вам использовать самые свежие средства обеспечения безопасности. Если в дальнейшем в PHP появится более сильный алгоритм хэширования, то ваш код станет использовать его автоматически.

password_verify()

Теперь рассмотрим функцию сравнения пароля с хэшем. Первый вводится пользователем, а второй мы берём из БД. Пароль и хэш используются в качестве двух аргументов функции password_verify(). Если хэш соответствует паролю, то функция возвращает true.

Помните, что соль является частью хэша, поэтому она не задаётся здесь отдельно.

password_needs_rehash()

Если вы захотите повысить уровень безопасности, добавив более сильную соль или увеличив стоимостный параметр, или изменится алгоритм хэширования по умолчанию, то вы, вероятно, захотите перехэшировать все имеющиеся пароли. Данная функция поможет проверить каждый хэш на предмет того, какой алгоритм и параметры использовались при его создании:

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

password_get_info()

Более ранние версии PHP

Как видите, работать с новым API не в пример легче, чем с неуклюжей функцией crypt(). Если же вы используете более ранние версии PHP, то рекомендую обратить внимание на библиотеку password_compact. Она эмулирует данный API и автоматически отключается, когда вы обновляетесь до версии 5.5.

Источник

Werther Blog’s

Ещё один мой сайт.

О себе:

Мне нечего рассказать.
Все, что я могу, — это рисовать внутренние органы и ненавидеть.
Я творение высшей расы.
Полон желчи, ненависти и пафоса.

Вы не сможете войти в круг моего доверия.
Не верьте мне, я вам не доверяю.

Рубрики

Архивы

Пароли, авторизация, md5 и его расшифровка

Итак, животрепещущий вопрос, не дающий покоя многим поколениям начинающих php-программистов: как расшифровать строку, зашифрованную функцией md5().

Ответ прост: никак.

Почему
md5() нельзя расшифровать, так как он ничего не шифрует. Он хеширует. Термина «расхешировать» нет.

Хеширование, это преобразование данных произвольного размера в короткую строку (или число) фиксированной длины. Для алгоритма md5 результатом является 32-разрядное 16-ричное число (называемое хешем или дайджестом).

Немного разбираясь в математике, можно сообразить: множество входных значений (строка произвольного размера), практически бесконечно, в то время как количество возможных результатов, представляет собой вполне конечное число — 16[sup]32[/sup]. Следовательно, взаимнооднозначного соответствия между двумя множествами быть не может. Следовательно, зная результирующий хеш, получить исходную строку невозможно, т.к. для одного хеша возможных исходных строк может быть любое количество.

Изначальная задача md5, вообще, ни к хранению паролей, ни к web-программированию не относится. Md5 вычисляет контрольные суммы. Например, при передаче большого файла по каналу связи, где возможны ошибки, вместе с ним можно передать его md5-хеш, после чего приемник также может вычислить хеш полученных данных и сравнить с пришедшим, чтобы удостовериться, что сбоев при передаче не произошло. Либо, вы можете распространять свою программу и выложить у себя на сайте хеш её архива. И пользователь, получивший её из других источников, может проверить, а не залезал ли в неё злой хакер и не прицепил ли в конце какой-нибудь вирус. Одно из свойств md5-алгоритма — значительное отличие хеша, даже при незначительных изменениях во входных данных.

Пароли пользователей обычно хранятся в базе или в файле. Хранить их можно и просто в открытом виде. Однако это является некоторой дырой в безопасности. Так как злоумышленник, получивший доступ только для чтения к этой базе, может взломать систему. Случай, когда он получает доступ еще и на запись, не рассматриваем, так как никакой md5() здесь уже не поможет.

Вообще-то, дыра в безопасности не в этом. При настройке БД вменяемым администратором, никто посторонний доступа получить не должен. Однако, народ у нас администраторам не доверяет и пароли в базе шифрует. То есть в большинстве случаев, как уже выяснили, не шифрует, а хеширует.

В большинстве случаев это выглядит следующим образом:

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

Подбор пароля при известном хеше
Как уже было сказано, исходный пароль узнать нельзя, т.к. одному хешу может соответствовать несколько исходных строк. Однако, искать исходный пароль и не нужно, достаточно найти любую из этих строк и отправить на сервер в качестве пароля. Две различные строки, дающие одинаковый хеш, называются коллизиями.

Поиск коллизии, имея из исходных данных только хеш, можно осуществить только одним способом — банальным перебором всех значений.

Время на подбор составляет: количество времени на вычисление хеша для одного значения x количество хешей, которые необходимо перебрать.

Количество перебираемых хешей пропорционально мощности множества всех возможных значений хеша, т.е. 16[sup]32[/sup], то есть, примерно, 10[sup]38[/sup]. С учетом того, что md5 достаточно длительный для вычисления алгоритм, время подбора выливается на современных компьютерах в достаточно ощутимый промежуток.

Хотя, это время подбора абстрактного значения.
Если у вас пароль может содержать латинские символы в обоих регистрах и цифры и иметь длину от 6 до 15 символов, то общее число вариантов —

А с учетом того, что большинство пользователей не будет набирать более 10 символов – 10[sup]18[/sup].
Что уже несколько веселее для взломщика. Если требуется подобрать пароль только к одному пользователю, имея базу по всем пользователям сайта, то делите это число еще и на их количество.

Обращаю внимание, что это средние теоретические цифры. Существует вероятность, что вы наткнетесь на нужный вариант уже на первой итерации. Примерно 1 на 10[sup]18[/sup].

Так же это все верно при случайной генерации пароля. Однако, треть учетных записей администраторов ломается вводом пароля «god». А еще треть – «admin».

Алгоритм хеширования
В простейшем случае пароль хешируется банально – md5($password). Однако, старателями уже собраны достаточно большие базы на md5-хеши. Немного изменив алгоритм, можно сделать их бесполезными.

Простой md5(md5($password)) увеличит время подбора вдвое. Добавьте туда логин, идентификатор пользователя и секретную строку: md5(md5($password.$login).$secret). Перемешайте все это и сделайте так, чтобы никто не узнал точный алгоритм. На каждом сайте немного изменяйте его.

Недостатки
С одной стороны плохие люди не могут получить исходный пароль. С другой — хорошие тоже. Наиболее неудобно это при восстановлении пароля. Выслать старый пароль нельзя. Поэтому либо приходится генерировать новый, либо давать пользователю специальную ссылку, где он сам может ввести нужный.

Автоматическая авторизация

Автоматическая авторизация позволяет пользователю не вводить пароль каждый раз при посещении сайта. Обычно это осуществляется при помощи кук.

В простейшем случае в куках хранятся логин и пароль в открытом виде. Это не совсем здорово, так как куки можно перехватить или просто подсмотреть в браузере. В FireFoxе это вообще делается просто в меню. Поэтому, перед сохранением в куки над этими данными так же следует немного поиздеваться.

Однако здесь нужно помнить следующую вещь – паролем является, по сути, не то, что вводит пользователь в форму, а то, что поступает на вход серверу. Если человек получает куки, которые посылаются серверу, он может послать их с тем же успехом, вне зависимости от того, открытый там пароль или хеш. По большому счету, основное преимущество – хеш сложнее визуально запомнить, чем обычный пароль.

Хранить авторизационные данные в куках можно по разному. Например, можно завести табличку в базе: id-пользователя => рандомный хеш. И хранить в куках этот самых хеш. При каждой авторизации его можно менять и перезаписывать куку. Можно привязать его к IP, чтобы, даже узнав его, плохие дяди не смогли попасть на сайт с другой машины. Но при этом пользователи модемов идут лесом.

Однако этим мы ставим под сомнения все предыдущие выкрутасы с паролем. Ведь, получив доступ к базе, хакер теперь может не подбирать пароль к хешу, а установить себе нужную куку.

Можно хранить в куках хеш по типу того, что в базе. Но нужно опять таки смотреть, чтобы не обесценить все наши попытки зашифровать пароль. Если хранить в базе и в куке одинаковый хеш, то опять все хеширования становятся бессмысленными. Даже при разных алгоритмах нужно долго думать. Например:

Ну и что? Узнав из базы hash2Base, элементарно вычисляем

и кладем себе в куку.

Вариантов масса. Главное понимать, что автоматической авторизацией мы открываем еще один вход на сайт и следить за всем приходится вдвое тщательнее.

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

Решается это просто — запрещением авторизоваться одному пользователю чаще определенного времени (да даже чаще двух секунд).
Блокированием IP, с которого идет слишком много вопросов. Можно сделать даже на уровне сервера. Правда, достаточно легко обходится путем использования прокси-серверов.

Даже без этих элементарных действий, важная помеха, это скорость ответа сервера. Если сценарий обрабатывается, например, 1 секунду процессорного времени, то чаще проверять пароль просто невозможно.

Подчеркиваю – процессорного времени. Не стоит пытаться защититься при помощи sleep(2) во время авторизации. Эта функция выводит процесс на заданное время из очереди процессов, и он не занимает ресурсов. Послав несколько запросов параллельно, хакер нейтрализует эту задержку.

Источник

Хеширование и расшифровка MD5 хеш-кода

Что такое MD5?

MD5 является одним из алгоритмов хеширования на 128-битной основе. Под хешированием понимают преобразование входных данных по определенному алгоритму в битовую строку определенной длины. При этом полученный в ходе вычислений результат представлен в шестнадцатеричной системе исчисления. Она называется хешем, хеш-суммой или хеш-кодом.

Процесс хеширования широко применяется в программировании и веб-индустрии. В основном для создания уникальных значений в ассоциативных массивах, идентификаторов.

Область применения хеш-кодов:

MD5 как стандарт хеширования был разработан в 1991 году для создания уникального хеш-кода от заданного значения с последующей проверкой его подлинности.

То есть хеш, полученный от функции, работа которой основана на этом алгоритме, выдает строку в 16 байт (128) бит. И эта строка включает в себя 16 шестнадцатеричных чисел. При этом изменение хотя бы одного ее символа приведет к последующему бесповоротному изменению значений всех остальных битов строки:

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Проблемы надежности MD5

Казалось бы, такая характеристика MD5 должна обеспечивать 100% гарантии неуязвимости и сохранения данных. Но даже этого оказалось мало. В ходе проводимых исследований учеными был выявлен целый ряд прорех и уязвимостей в этом уже распространенном на тот момент алгоритме. Основной причиной слабой защищенности MD5 является относительно легкое нахождение коллизий при шифровании.

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

То есть большая вероятность расшифровки паролей MD5 является основной причиной отказа от использования этого алгоритма. Многие криптологи ( специалисты по шифрованию данных ) связывают низкую надежность MD5 с малой длиной получаемого хеш-кода.

Область применения алгоритма хеширования:

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Обзор средств для декодирования хеш-кода MD5

Иногда при работе с компьютером или поврежденными базами данных требуется декодировать зашифрованное с помощью MD5 значение хеша.

Удобнее всего использовать специализированные ресурсы, предоставляющие возможность сделать это online :

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

почему нельзя расшифровать md5. Смотреть фото почему нельзя расшифровать md5. Смотреть картинку почему нельзя расшифровать md5. Картинка про почему нельзя расшифровать md5. Фото почему нельзя расшифровать md5

Если происмотреться к значениям декодинга, отображенных на показонном выше рисунке, то становится понятно, что процесс расшифровки почти не дает результатов. Эти ресурсы представляют собой одну или несколько объединенных между собой баз данных, в которые занесены расшифровки самых простых слов.

При этом данные декодирования хеша MD5 даже такой распространенной части пароля как « админ » нашлись лишь в одной базе. Поэтому хеши паролей, состоящих из более сложных и длинных комбинаций символов, практически невозможно расшифровать.

Основы безопасности при использовании MD5

Этот стандарт кодирования является одним из самых распространенных методов защиты данных не только в прикладном, но и в веб-программировании. Поэтому не будет лишним обезопасить свой md5 hash от намеренного взлома.

Основным способом, гарантирующим безопасность хеша вашего пароля, является использование « соли ». Он основан на добавлении к паролю нескольких случайных символов и последующем хешировании результата.

Во многих языках программирования для этого используются специальные классы и функции. Не являются исключением из правил и серверные языки программирования.

Создать хеш-код MD5 в php можно с помощью нескольких функций:

При использовании функции md5() в PHP для задания значения соли используют методы генерации случайных чисел. Например, rand() :

Кроме применения « соли » было разработано еще несколько методов защиты хеша MD5 :

В статье приведены лишь начальные сведения об обеспечении безопасности хеша, полученного с помощью этого алгоритма. Самым простым и эффективным из них является использование уникального значения « соли », которая позволяет существенно « насолить » злоумышленнику и « подсластить » жизнь владельцу взламываемого пароля.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *