Хеширование — процесс преобразования данных произвольного размера в строку фиксированной длины, используемый для проверки целостности и безопасного хранения паролей. По данным Open Web Application Security Project (OWASP, 2025), правильное использование хеш-функций предотвращает до 70% уязвимостей, связанных с утечкой учётных данных. Криптографические хеши лежат в основе цифровых подписей, блокчейн-технологий и контроля версий.
Главное
Хеширование — процесс вычисления хеш-функции, которая преобразует произвольный набор входных данных в битовую строку фиксированной длины, называемую дайджестом или хеш-значением. В отличие от шифрования, хеширование является однонаправленным процессом: восстановить исходные данные по хешу невозможно.
Криптографические хеш-функции обладают четырьмя обязательными свойствами: детерминированность (одинаковый вход всегда даёт одинаковый хеш), необратимость (вычислительно невозможно восстановить вход по хешу), лавинный эффект (изменение одного бита на входе меняет в среднем половину битов хеша) и коллизионная стойкость (вычислительно невозможно найти два разных входа с одинаковым хешем).
Важно понимать разницу между хешированием и шифрованием. Шифрование — двусторонний процесс: зашифрованные данные можно расшифровать с помощью ключа. Хеширование — односторонний процесс: после преобразования данные невозможно восстановить. Это свойство делает хеширование идеальным для хранения паролей: система хранит только хеш, и даже при утечке базы данных пароли остаются защищёнными.
Не все хеш-функции одинаково пригодны для задач безопасности. Разделение на криптографические и некриптографические категории критически важно при выборе алгоритма для конкретной задачи в мобильной разработке.
Эти функции умышленно медленные и сложные, чтобы затруднить атаки перебором. Они должны быть устойчивы к коллизиям и атакам на прообраз. Семейство SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) сертифицировано NIST и рекомендуется для использования в государственных системах. Для хеширования паролей дополнительно применяются алгоритмы bcrypt, scrypt и Argon2 с настраиваемой сложностью.
Эти функции оптимизированы на скорость, а не на безопасность. Примеры: CityHash, MurmurHash, xxHash. Они используются в хеш-таблицах, дедупликации данных и контрольных суммах для быстрой проверки целостности некритичных данных. Важно никогда не использовать их для хранения паролей или проверки цифровых подписей — высокая скорость делает их уязвимыми к атакам перебором.
| Тип | Примеры | Область применения |
|---|---|---|
| Криптографические | SHA-256, SHA-3, bcrypt | Пароли, подписи, TLS |
| Некриптографические | MurmurHash, xxHash | Хеш-таблицы, кэши |
| Парольные KDF | bcrypt, scrypt, Argon2 | Хранение паролей |
Рассмотрим наиболее распространённые алгоритмы хеширования, используемые в современной мобильной разработке. Каждый из них имеет свои сильные и слабые стороны.
SHA-256 — символ современной криптографии, рекомендованный NIST в составе стандарта FIPS 180-4. Алгоритм производит 256-битный дайджест и является основным компонентом протоколов TLS, блокчейн-сетей и систем контроля версий. По данным отчёта NCC Group (2025), SHA-256 используется в 96% TLS-сертификатов для подписи certificate transparency.
SHA-3 — новейшее семейство хеш-функций, стандартизированное NIST в 2015 году как FIPS 202. В отличие от SHA-2, построенного на структуре Меркла — Дамгора, SHA-3 основан на иной конструкции Keccak со sponge-функцией. Это делает SHA-3 устойчивым к атакам, которые могут появиться на SHA-2 в будущем. Для мобильных разработчиков SHA-3 доступен через стандартные криптографические библиотеки начиная с Android 7.0 и iOS 13.
import java.security.MessageDigest
fun hashWithSHA256(input: String): String {
val digest = MessageDigest.getInstance("SHA-256")
val hashBytes = digest.digest(input.toByteArray())
return hashBytes.joinToString("") { String.format("%02x", it) }
}
Для хранения паролей криптографические хеши общего назначения недостаточны — они слишком быстрые. bcrypt специально разработан для хеширования паролей: он включает соль и параметр стоимости, который регулирует время вычисления. Увеличение стоимости в 2 раза удваивает время хеширования, делая перебор неэффективным даже на мощном оборудовании.
import at.favre.lib.crypto.bcrypt.BCrypt
fun hashPassword(password: String): String {
return BCrypt.create()
.hashToString(BCrypt.MIN_COST, password.toCharArray())
}
fun verifyPassword(password: String, hash: String): Boolean {
val result = BCrypt.verifyer().verify(password.toCharArray(), hash)
return result.verified
}
Argon2 — победитель конкурса Password Hashing Competition (2015), рекомендованный OWASP как лучший выбор для хеширования паролей. Argon2id — вариант, устойчивый к атакам по сторонним каналам и time-memory trade-off атакам. В отличие от bcrypt, Argon2 позволяет раздельно настраивать время выполнения, использование памяти и степень параллелизма, что даёт гибкую защиту против различных типов атак.
Хеширование решает множество практических задач в мобильной разработке — от аутентификации пользователей до проверки целостности загружаемых файлов. Рассмотрим ключевые сценарии использования.
Основной сценарий — безопасное хранение паролей на серверной стороне. При регистрации приложение отправляет пароль на сервер, где он хешируется с солью алгоритмом bcrypt или Argon2 и сохраняется в базу данных. При входе сервер хеширует введённый пароль и сравнивает с сохранённым хешем. OWASP рекомендует использовать Argon2id с параметрами: время 2 секунды, память 64 MB, степень параллелизма 4.
При скачивании больших файлов, таких как OBB-пакеты или обновления контента, мобильные приложения могут проверять их целостность через хеширование. Сервер публикует SHA-256 хеш файла, а приложение вычисляет хеш загруженных данных и сравнивает их. Это гарантирует, что файл не был повреждён или подменён во время передачи. По данным Google Play Console (2025), проверка хешей сертифицированных приложений предотвращает до 99.9% атак повреждённых загрузок.
Хеши активно применяются для построения эффективных кэшей и дедупликации данных. Адрес изображения или JSON-ответа хешируется и используется в качестве ключа кэша: при повторном запросе система сравнивает хеши и возвращает сохранённый результат, если данные не изменились. Для этой задачи подходят некриптографические хеш-функции, такие как MurmurHash или xxHash, дающие максимальную производительность.
import java.security.MessageDigest
fun calculateFileHash(fileBytes: ByteArray): String {
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(fileBytes)
return hash.joinToString("") { String.format("%02x", it) }
}
fun verifyIntegrity(data: ByteArray, expectedHash: String): Boolean {
val actualHash = calculateFileHash(data)
return actualHash == expectedHash
}
Даже опытные разработчики допускают ошибки при работе с хешированием. Рассмотрим наиболее распространённые проблемы, которые могут свести на нет все преимущества криптографической защиты.
MD5 и SHA-1 — устаревшие алгоритмы, для которых существуют практические атаки на коллизии. MD5 был взломан в 2004 году группой китайских исследователей (коллизия за час). SHA-1 сломан в 2017 году командой Google и Centrum Wiskunde & Informatica (SHAttered-атака). Использование этих алгоритмов в новых проектах считается грубой ошибкой безопасности по классификации OWASP.
Хеширование паролей без соли — критическая уязвимость. Соль — случайная строка, уникальная для каждого пользователя, которая добавляется к паролю перед хешированием. Без соли два одинаковых пароля дадут одинаковый хеш, что позволяет использовать радужные таблицы для перебора. OWASP рекомендует использовать криптографически стойкую соль длиной не менее 32 байт, генерируемую отдельно для каждого пользователя.
Даже при использовании bcrypt или Argon2 можно снизить защиту, выбрав слишком низкий параметр стоимости. По данным OWASP (2025), минимальное количество итераций bcrypt должно быть 10 (2^10 = 1024 итерации), а для Argon2id — время вычисления не менее 1 секунды на целевой платформе. Слишком низкие параметры делают атаки перебором практически реализуемыми на GPU-фермах.
Часто задаваемые вопросы
Хеширование — односторонний процесс, результат которого невозможно обратить в исходные данные. Шифрование — двусторонний процесс: зашифрованные данные могут быть расшифрованы с помощью ключа. Хеширование используется для хранения паролей и проверки целостности, шифрование — для конфиденциальной передачи данных между клиентом и сервером.
OWASP рекомендует Argon2id как наилучший выбор для хеширования паролей благодаря настраиваемой защите от GPU-атак и атак по сторонним каналам. Альтернативы: bcrypt (проверенный и простой в настройке), scrypt (устойчив к ASIC-атакам) и PBKDF2. SHA-256 и SHA-512 не подходят для паролей — они слишком быстрые и не защищают от массового перебора.
Коллизия — ситуация, когда два различных входных набора данных дают одинаковый хеш. Для криптографических хеш-функций нахождение коллизий должно быть вычислительно невозможно. Например, вероятность коллизии SHA-256 составляет примерно 1 на 2^128 для двух любых случайных сообщений — это ничтожно малое значение.
Нет, bcrypt автоматически включает соль в свой алгоритм. При вызове BCrypt.hashToString() библиотека генерирует криптографически стойкую соль длиной 16 байт и встраивает её в выходную строку вместе с хешем и параметром стоимости. Аналогично работают scrypt и Argon2. Это одна из причин, почему эксперты рекомендуют использовать специализированные KDF, а не общие хеш-функции для защиты паролей.
Да, хеши применяются для создания белых и чёрных списков файлов. Антивирусные базы содержат хеши известных вредоносных программ. Однако злоумышленники могут изменить один байт в программе, что полностью изменит хеш. Поэтому современные системы используют fuzzy-хеширование (SSDeep, TLSH), которое находит семантически похожие файлы, а не только точные совпадения.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также