SHA-1, SHA-2, SHA-256, SHA-384 — Что такое хеш ( Hash — hashing algorithm )
Алгоритм хеширования — это математическая функция, которая уплотняет данные до фиксированного размера. Иногда хеширование называется односторонним шифрованием. Например берем предложение «Что такое хеширование и как с ним бороться» пропускаем его через специальный алгоритм хеширования и получаем щось типа «078945aDf» — этот результат называется хешем (hash) от приведенного предложения. Если необходимо сравнить два файла, то проще сначала вычислить их хеши и сравнить их хеши, чем посимвольно сравнивать два файла. Очень удобно и безопасно получается например для хранения паролей в базе — достаточно сравнить хеш установленного пароля и хеш введенного пароля чтобы удостовериться что введен правильный пароль, плюс сам то пароль не хранится в базе, и это прекрасно с точки зрения безопасности
Существуют сотни алгоритмов хеширования, и все они имеют конкретные цели — некоторые оптимизированы для определенных типов данных, другие — для скорости, безопасности и т. д. SHA расшифровывается как алгоритм безопасного хеширования, он предназначен для криптографической безопасности.
Криптографические алгоритмы хеширования SHA создают необратимые и уникальные хэши.
Необратимый хеш означает, что если у вас есть хеш вы не сможете восстановить исходный фрагмент данных.
Уникальный хеш означает что два разных фрагмента данных никогда не могут создавать один и тот же хеш.
Протокол SSL / TLS используется для обеспечения безопасной передачи данных с одного устройства на другое. SSL сертификат обеспечивает «шифрование» а также обеспечивает аутентификацию. Задача сертификата SSL — предоставить необходимую информацию для аутентификации. Сертификаты SSL связывают определенный открытый ключ с организацией. Протокол SSL / TLS обеспечивает соединение с использованием асимметричного шифрования. Это означает, что есть два ключа шифрования, каждый из которых обрабатывает половину процесса: открытый ключ для шифрования и закрытый ключ для дешифрования. Каждый SSL-сертификат содержит открытый ключ, который используется клиентом для шифрования данных, а владелец SSL-сертификата использует закрытый ключ для расшифровки этих данных. В конечном счете, основной задачей асимметричного шифрования для HTTPS является безопасный обмен сеансовыми симметричными ключами .
Цифровые подписи являются важной частью того, как сертификаты SSL обеспечивают аутентификацию. SSL сертификат подписывается цифровой подписью центра сертификации DigiCert. Эта подпись предоставляет криптографическое доказательство того, что ЦС подписал сертификат SSL и что сертификат не был изменен или воспроизведен. Подпись является доказательством того, что информация, содержащаяся в сертификате, была проверена доверенной третьей стороной — Центром сертификации. ЦС сначала хэширует файл сертификата и подписывает полученный хэш. Это более эффективно, чем подписывать весь сертификат. Цифровая подпись обеспечивают необходимое доказательство того, что сертификат, который вы получили, является точным сертификатом, выданным доверенным центром сертификации для данного веб-сайта. Цифровые подписи чрезвычайно чувствительны — любое изменение в файле приведет к изменению хеша подписи. Это делает невозможным для злоумышленника изменить законный сертификат или создать поддельный сертификат, который выглядит законным.
SHA-1 и SHA-2
SHA обозначает алгоритм безопасного хеширования. SHA-1 и SHA-2 — две разные версии этого алгоритма. Они отличаются как полученный хеш создается из исходных данных и по длине в битах подписи. SHA-1 — это 160-битный хеш. SHA-2 является «семейством» хэшей и имеет различную длину, наиболее популярной из которых является 256-битная. Есть «SHA-224», «SHA-384» «SHA-512». С 2011 по 2015 год SHA-1 был основным алгоритмом, с 2016 года SHA-2 является новым стандартом. (Хронология перехода сохранена ниже для истории 😉
Переход с алгоритма хэширования SHA-1 на SHA-2 ( SHA-256 ) с 1 января 2017
Использование SHA-1 в качестве алгоритма хеширования для подписи сертификатов не одобрялось, а теперь и вовсе не рекомендуется. 😉
Основная причина проблемы — известная уязвимость алгоритма хэширования SHA-1, которая делает возможными атаки, приводящие к конфликтам. Эти атаки могут позволить злоумышленнику создать дополнительные сертификаты, обладающие той же цифровой подписью, что и исходный сертификат.
Microsoft опубликовал рекомендации по безопасности «Deprecation of SHA-1 Hashing Algorithm for Microsoft Root Certificate Program». и перестал принимать SHA-1 сертификаты с 1 января 2017 года. Чтобы работать с платформами Microsoft, все SHA-1 SSL сертификаты должны быть заменены на SHA-256 (SHA-2).
SSL сертификаты с окончанием срока действия после 1 января 2017 должны использовать SHA-2
CodeSigning сертификаты с окончанием срока действия после 1 января 2016 должны использовать SHA-2
DV OV EV WC SAN PRO CodeSign Email PDF Wi-Fi IoT ALL Купить сертификат

Copyright © 1997-2024 adgrafics
SHA1
В криптографии SHA-1 (Secure Hash Algorithm 1) — это криптографическая хэш-функция, которая принимает входные данные и создает 160-битное (20-байтовое) хэш-значение, известное как дайджест сообщения, обычно отображаемое как шестнадцатеричное число длиной 40 цифр. Он был разработан агентством национальной безопасности США и Федеральному стандарту обработки информации США.
С 2005 года SHA-1 не считается защищенным от хорошо финансируемых оппонентов, и с 2010 года многие организации рекомендовали его замену на SHA-2 или SHA-3. Microsoft, Google, Apple и Mozilla объявили, что их соответствующие браузеры прекратят принимать SSL-сертификаты SHA-1 к 2017 году.
В 2017 году CWI Амстердам и Google объявили, что они совершили атаку столкновения против SHA-1, опубликовав два разнородных PDF-файла, которые произвели тот же хэш SHA-1.
Как и зачем переходить с SHA-1 на SHA-2 и почему это важно
Индустрия инфраструктуры открытых ключей (ИОК, англ. PKI — Public Key Infrastructure) рекомендует, чтобы любой объект инфраструктуры, использующий SHA-1, был переведён на более безопасный SHA-2. В этой статье описано, почему и как стоит это сделать.
В 2016 году миграция на SHA-2 была хорошей подготовкой к всеобщему дедлайну, сейчас же этот переход обязателен для обеспечения безопасности. Многие устройства и приложения, использующие электронные сертификаты, уже сейчас выводят предупреждения или ошибки или отказываются работать, если сертификат использует алгоритмы хеширования SHA-1 или старше. Зачем эти принудительные изменения? Потому что в хеше SHA-1 обнаружены серьёзные криптографические уязвимости, и дни, когда его защита ещё надёжна, уже сочтены.
Вплоть до 2017 года SHA-1 был самым популярным хешем, используемым для криптографической подписи, и некоторые, в особенности старые, приложения и устройства не принимали или не понимали хеши или сертификаты, основанные на алгоритме SHA-2. Это было основной проблемой перехода на новый стандарт.
Что такое хеш?
Криптографическая хеш-функция — это математический алгоритм, преобразующий любое уникальное сообщение (текст, видео, аудио, изображение и т. д.) в уникальную комбинацию, которую чаще всего называют «хешем» или «хеш-кодом». Два разных сообщения ни в коем случае не должны преобразовываться в одинаковый хеш, а два идентичных сообщения всегда должны возвращать один и тот же хеш. Благодаря этим свойствам хеш-код может использоваться для сравнения двух различных сообщений на идентичность. Криптографические хеши являются основой для практически любой цифровой аутентификации и проверки целостности файла.
Службы центра сертификации (ЦС) ИОК используют криптографические хеш-функции для подтверждения идентификационных данных и запросов цифровых сертификатов. Кроме этого, хеши используются для подтверждения цифровых сертификатов (например, цифровой подписью) и списка аннулированных сертификатов (CRL, certificate revocation list), которые выдают другие доверенные стороны. Доверенные стороны не смогут полагаться на достоверность цифровых сертификатов и другого контента, подписанного ЦС, если службы ИОК используют ненадёжный криптографический хеш. Стойкость криптографического хеша создаёт доверие ко всей системе ИОК.
Примечание: контрольные суммы — это хеш-подобные верификаторы, но без криптографических доказательств, подтверждающих, что они обеспечивают статистически уникальные результаты для уникальных входных сообщений.
В общем, криптографические хеши считаются более безопасными, чем контрольные суммы, хотя последние часто используются для некритических проверок целостности и подлинности.
Атаки на хеши
Стойкость криптографической хеш-функции в том числе обеспечивается тем, что для любого уникального сообщения формируется уникальный хеш. В то же время необходимо, чтобы по одному только хешу нельзя было воспроизвести исходное сообщение. На попытке обойти это свойство строится атака нахождения прообраза. Кроме того, два разных сообщения ни в коем случае не должны преобразовываться в одинаковые хеши, иначе возникнет явление, которое называется коллизией. На этом явлении основывается атака «дней рождения».
Общепринятые криптографические хеш-функции изначально считаются криптографически стойкими, но со временем злоумышленники находят математические уловки, ослабляющие их защиту.
Вычислительная сложность криптостойкого хеша равна заявленной эффективной длине последовательности бит минус 1. Таким образом, когда неизвестны его недостатки, 128-битный хеш будет иметь сложность вычисления 2^127. Как только кто-то найдёт математический алгоритм, который позволит взломать хеш за время меньшее, чем эффективная длина бит минус 1, такой хеш будет считаться ослабленным. Как правило, все общепринятые хеши становятся слабее со временем. Когда эффективная длина бит сокращается, хеш становится менее защищённым и менее ценным. Когда считается, что хеш может быть взломан за разумный период времени и с не столь значительными вычислительными ресурсами (стоимостью от сотен тысяч до миллионов долларов), то хеш считается «взломанным» и не должен больше использоваться. Взломанные хеши используются вредоносными программами и злоумышленниками для создания якобы законного программного обеспечения с цифровой подписью. Хороший пример такого ПО — Flame malware program. В общем, слабые хеши могут сыграть свою роль и не должны использоваться.
Введение в семейство SHA
Алгоритм SHA-1 был разработан Агентством национальной безопасности США (АНБ) и опубликован Национальным институтом стандартов и технологий США (NIST) в качестве федерального стандарта в 1995 году. Выпущенные NIST криптографические стандарты пользуются доверием по всему миру и как правило требуются на всех компьютерах, используемых правительством или вооружёнными силами Соединённых Штатов. SHA-1 заменил предыдущие ослабевшие хеш-функции, например, MD5.
Со временем несколько непрерывных криптографических атак на SHA-1 уменьшили эффективность длины ключа. Из-за этого в 2002 году АНБ и NIST выбрали SHA-2 новым рекомендуемым стандартом хеширования. Это случилось задолго до того, как SHA-1 начали считать взломанным. В феврале 2017 года обнаружили успешную атаку на хеш с помощью коллизий, которая сделала SHA-1 бесполезным для защиты электронной подписи.
Отличное обсуждение взлома SHA-1 и пример документации можно найти здесь.
Семейство SHA-2
SHA-2 — стандарт криптографического хеширования, который программное и аппаратное обеспечение должны использовать по крайней мере ближайшие пару лет. SHA-2 очень часто называется семейством хеш-функций SHA-2, поскольку содержит много хешей разных размеров, включая 224-, 256-, 384- и 512-битные последовательности. Когда кто-то говорит, что использует SHA-2, длина его хеша неизвестна, но сейчас самый популярный — 256-битный. Хотя некоторые математические характеристики SHA-2 совпадают с SHA-1, и в нём обнаружены незначительные недостатки, в криптомире он по-прежнему считается «стойким». Без сомнения, он лучше, чем SHA-1 и чем любой критический сертификат, приложение или аппаратное устройство, использующие SHA-1. Всё, что использует SHA-1, лучше перевести на SHA-2.
Обработка устаревших хэшей SHA-1
Все крупные поставщики веб-браузеров (например, Microsoft, Google, Mozilla, Apple) и другие доверенные стороны рекомендовали всем клиентам, сервисам и продуктам, в настоящее время использующим SHA-1, перейти на SHA-2, хотя что и когда должно перейти зависит от поставщика. Например, многие поставщики заботятся только о сертификатах TLS (т. е. веб-серверах), и только компания Microsoft озабочена использованием SHA-1 в цифровом сертификате от «публичного» центра сертификации. Но можно ожидать, что все поставщики потребуют перевести на SHA-2 все приложения и устройства, даже если они не готовы к этому. Сейчас большинство браузеров покажет сообщение об ошибке, если на веб-сайте используется публичный цифровой сертификат, подписанный SHA-1, но некоторые из них позволят вам обойти всплывающее окно и перейти на такой сайт. Возможно, в скором времени, все главные поставщики браузеров запретят обход сообщений об ошибке и переходы на сайты, использующие цифровые сертификаты SHA-1.
К сожалению, переход с SHA-1 на SHA-2 является односторонней операцией в большинстве сценариев сервера. Например, как только вы начнёте использовать цифровой сертификат SHA-2 вместо SHA-1, пользователи, не понимающие сертификаты SHA-2, начнут получать предупреждения и уведомления об ошибках, или даже отказы. Для пользователей приложений и устройств, не поддерживающих SHA-2, переход будет опасным скачком.
План перехода ИОК с SHA-1 на SHA-2
Каждая компания с внутренним ИОК, не использующая SHA-2, должна будет создать ИОК SHA-2 или перевести существующую ИОК с SHA-1 на SHA-2. Для перехода нужно:
- Обучить вовлечённых членов команды тому, что такое SHA-2 и почему требуется его использование (эта статья будет хорошим началом).
- Провести инвентаризацию всех критических хешей или цифровых сертификатов, используемых в приложениях или устройствах.
- Определить, какие критически важные устройства или приложения могут использовать SHA-2, какой размер ключа может быть использован и какие операционные проблемы могут возникнуть (этот этап зачастую включает обращение к поставщику и тестирование).
- Определить, какие компоненты ИОК могут или должны быть перенесены в SHA-2.
- Составить план перехода для преобразования компонентов SHA-1 в SHA-2, включая потребителей и компоненты ИОК, плюс резервный план на случай сбоя.
- Провести PoC-тестирование.
- Принять управленческий риск и решение о переходе или отказе от него.
- Внедрить план перехода в производственную среду.
- Провести тестирование и получить обратную связь.
Самая сложная часть перехода — определение того, какие устройства и приложения работают с SHA-2. Если используемые устройства не понимают SHA-2, вас ждёт неудача или сообщение об ошибке, которое вряд ли будет звучать как «SHA-2 не принят». Вместо этого готовьтесь к: «Сертификат не распознан», «Соединение нестабильно», «Соединение не может быть установлено», «Повреждённый сертификат» или «Непроверенный сертификат».
Подумайте о своей миссии, чтобы определить, какие важные части вашей инфраструктуры будут или не будут работать. Начните с попытки инвентаризации каждого уникального устройства, ОС и приложения, которые должны понимать SHA-2. Затем соберите команду людей, которые протестируют, работает ли SHA-2. Можно предварительно полагаться на информацию от поставщиков, но вы не будете знать наверняка пока не проверите самостоятельно.
Обновление приложений и устройств — задача не из лёгких, и потребует больше времени, чем кажется. Даже сейчас существует множество устройств и приложений, использующих старые версии OpenSSL, которые следовало бы обновить после атаки Heartbleed, но администраторы серверов этого так и не сделали.
Если у вас есть внутренняя ИОК, вам понадобится подготовить её к переходу на SHA-2. Иногда это означает обновление ваших центров сертификации, получение новых сертификатов или установку полностью новых ИОК. Последнее рекомендуется по множеству причин, в основном потому, что новая ИОК даст вам шанс начать сначала без груза старых ошибок.
Модели перехода ИОК
Ниже перечислены сценарии для внедрения SHA-2 в компоненты ИОК (для этих примеров используется двухуровневая ИОК — автономная корневая система, онлайн центры сертификации), каждый из которых может быть либо новым компонентом, либо перенесённым:
- Два ИОК дерева, один полностью SHA-1, другой полностью SHA-2.
Остальные сценарии предполагают одно дерево ИОК:
- Всё дерево ИОК, от корня до конечных точек, — SHA-1.
- Всё дерево ИОК, от корня до конечных точек, — SHA-2.
- Корень — SHA-1, выдающие ЦС — SHA-2, сертификаты конечных точек — SHA-2.
- Корень — SHA-1, выдающие ЦС — SHA-2, сертификаты конечных точек — SHA-1.
- Корень — SHA-1, выдающие ЦС — SHA-2 и SHA-1, сертификаты конечных точек — SHA-2 и SHA-1.
- Корень — SHA-2, выдающие ЦС — SHA-1, сертификаты конечных точек — SHA-1.
- Корень — SHA-2, выдающие ЦС — SHA-2, сертификаты конечных точек — SHA-1.
- Корень — SHA-2, выдающие ЦС — SHA-2 и SHA-1, сертификаты конечных точек — SHA-2 и SHA-1.
Также возможно существование выдающего центра сертификации, который переключается между SHA-1 и SHA-2 по необходимости, но это с большой вероятностью вызовет путаницу в службах ИОК (и не особо рекомендуется). Если возможно, для облегчения перехода можно запустить параллельные ИОК, один — с SHA-1, другой — с SHA-2, а потом переводить используемые устройства после того, как позволит тестирование.
Примечание: собственный сертификат ЦС корневого ЦС не нужно переносить на SHA-2, даже если он всё ещё использует SHA-1. Все программы проверки устаревших SHA-1 заботятся обо всём после собственного сертификата корневого ЦС (и будут заботиться, по крайней мере, в обозримом будущем). Тем не менее, имеет смысл переместить всё, включая собственный сертификат ЦС корневого ЦС на SHA-2, чтобы можно было сказать, что вся ИОК — SHA-2, и избежать дальнейших изменений, связанных с SHA-1, в обозримом будущем.
Публичные ЦС уже перешли с SHA-1 на SHA-2 для любых сертификатов со сроком жизни, заканчивающимся после 1 января 2017, поэтому вы должны сосредоточить свои усилия на серверах и приложениях с ещё не перешедшими на SHA-2 публичными цифровыми сертификатами. После решения этой проблемы можно начать смотреть на внутренние ИОК и доверенные стороны. Переход с SHA-1 на SHA-2 технически не сложен, но это массовое логистическое изменение с множеством последствий, которое требует продолжительного тестирования.
Вряд ли большинство поставщиков знают точную дату смерти SHA-1 (т. е. дату, когда его использование в приложении или устройстве будет приводить к «фатальным» ошибкам), но скорее всего это произойдёт раньше, чем вы ожидаете, так как всё больше пользователей переходит на SHA-2. Поэтому вам действительно стоит совершить переход уже сейчас.
SHA-3 уже здесь, но стоит ли его использовать?
Хотя в SHA-2 не обнаружено существенных криптографических слабостей, он считается алгоритмически схожим с SHA-1. Большинство экспертов думают, что его время жизни будет схожим с SHA-1. В августе 2015 NIST утвердило новый алгоритм криптографического хеширования SHA-3. Он не обладает теми же математическими свойствами, что SHA-1 и SHA-2 и должен быть более устойчив к криптографическим атакам, чем его предшественники.
К сожалению, люди, откладывающие свой переход на SHA-2 в надежде сразу перейти на SHA-3, будут очень расстроены. Общемировое принятие стандарта SHA-3 может затянуться на долгие годы, а переход на SHA-2 следует сделать уже сейчас. Если вы перейдёте на SHA-3 сейчас, то большинство, если не все, ваших криптографически-зависимых приложений или устройств, скорее всего, сообщат об ошибке (не смогут распознать цифровой сертификат).
Итак, если вы ещё не перешли на SHA-2, то переходите сейчас. И когда SHA-2 начнёт ослабевать, мы все вместе перейдём на SHA-3.
6.18 Алгоритм вычисления дайджеста сообщения (SHA1, RFC-3174, сентябрь 2001)
Алгоритм SHA-1 (Secure Hash Algorithm) предназначен для вычисления дайджеста документа, файла или сообщения. Когда входное сообщение имеет произвольную длину 64 бит, программа SHA-1 выдает 160-битовый код, называемый дайджестом сообщения. Дайджест сообщения может стать, например, исходной информацией для для алгоритма электронной подписи, которая формируется для верификации сообщения. Подпись сообщения улучшает эффективность процесса, так как дайджест обычно имеет размер много меньше размера сообщения. Тот же самый алгоритм используется при верификации цифровой подписи. Любая модификация сообщения при транспортировке с крайне высокой вероятностью приведет к тому, что дайджест изменится и подпись не будет верифицирована.
Позднее были разработаны более эффективные версии SHA-2 (2001, 256-512 бит) и SHA-3 (Йоан Даймен, 2013, 256-512 бит).
| Алгоритм | Размер сообщения в битах | Размер блока в битах | Размер слова в битах | Размер дайджеста сообщения в битах |
|---|---|---|---|---|
| SHA-1 | < 2 64 | 512 | 32 | 160 |
| SHA-224 | < 2 64 | 512 | 32 | 224 |
| SHA-256 | < 2 64 | 512 | 32 | 256 |
| SHA-384 | < 2 128 | 1024 | 64 | 384 |
| SHA-512 | < 2 128 | 1024 | 64 | 512 |
| SHA-512/224 | < 2 128 | 1024 | 64 | 224 |
| SHA-512/256 | < 2 128 | 1024 | 64 | 256 |
Алгоритм SHA-1 называется безопасным, так как на его основе невозможно вычислить сообщение, которому соответствует дайджест, или найти другое сообщение, которое может соответствовать полученному дайджесту. Любое изменение сообщения при передаче приведет с большой вероятностью к существенному изменению дайджеста, что исключит успешную сверку цифровой подписи.
В разделе 2 определены терминология и функции, использованные при построении формы SHA-1.
2. Определение битовых строк и целых
В описании используются обозначения для битовых последователей и целых чисел:
- Шестнацатеричные цифры — это . Шестнацатеричные числа A представляются в виде 4-битовых строк. Примеры: 7 = 0111, A = 1010.
- Слово соответствует 32-битной строке, которая может быть представлена последовательностью из 8 hex цифр. Чтобы преобразовать слово в 8 hex-цифр, каждая 4-битная строка преобразуется в ее hex-эквивалент, как это описано выше в (a). Пример:
1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23. - Целое между 0 и 2 32 — 1 включительно может рассматриваться как слово. Младшие четыре бита этого целого представляют собой самую правую hex-цифру слова. Например: целое 291 = 2 8 +2 5 +2 1 +2 0 = 256+32+2+1 представляется hex-словом, 00000123.
Если z является целым, 0 64 , тогда z = (2 32 )x + y где 0 32 и 0 32 . Так как x и y могут быть представлены как слова X и Y, соответственно, z может быть представлен парой слов (X,Y).
3. Операция над словами
Со словами будут производиться следующие операции:
-
Побитовые логические операции над словами
X AND Y = побитовая логическая "and" X и Y. X OR Y = побитовая логическая "inclusive-or" X и Y. X XOR Y = побитовая логическая "exclusive-or" X и Y. NOT X = побитовая логическая "complement" X.
01101100101110011101001001111011 XOR 01100101110000010110100110110111 -------------------------------- = 00001001011110001011101111001100
Вычислим z = (x + y) mod 232.
Затем 0 32 . Преобразуем z в слово, Z, и определяем Z = X + Y.
4. Дополнение сообщений
SHA-1 используется для вычисления дайджеста сообщения или информационного файла, который поступает на вход. Сообщение или информационный файл должны рассматриваться как битовая строка. Длина сообщения является числом бит в сообщении (пустое сообщение имеет длину 0). Если число бит в сообщении кратно 8, ради компактности будем представлять сообщение в hex-формате. Целью дополнения сообщения является желание сделать полную длину сообщения кратной 512. В процессе расчета дайджеста сообщения SHA-1 последовательно обрабатывает блоки последовательность 512 бит. Далее специфицируется, как осуществляется дополнение исходного сообщения. Добавляется 1, за которой следует m «0» и 64-битное целое, чтобы получить сообщение с длиной, кратной 512. 64-битное целое характеризует длину исходного сообщения. Дополненное сообщение затем обрабатывается SHA-1 как n 512-битных блоков.
Предположим, что сообщение имеет длину l 64 . Прежде чем оно будет подано на вход SHA-1, сообщение дополняется справа следующим образом:
- Добавляем к сообщению «1». Например: если исходное сообщение «01010000», то после дополнения получаем «010100001».
- Добавляются «0». Число нулей зависит от длины исходного сообщения. Последние 64 бита последнего 512-битного блока зарезервированы для длины l исходного сообщения.
Пример: Предположим, что оригинальное сообщение является строкой бит
01100001 01100010 01100011 01100100 01100101.
После шага (a) это дает
01100001 01100010 01100011 01100100 01100101 1.
Так как l = 40, число бит в строке вше равно 41 и добавляется 407 «0», доводя длину сообщения до 448. Это дает в шестнацатеричном представлении
61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000.
Пример: Предположим, что мы имеем исходное сообщение (b). Тогда l = 40 (заметим, что l вычисляется до выполнения дополнений). Представление двух слов 40 в hex-формате 00000000 00000028. Следовательно дополненное сообщение в окончательном hex-формате будет иметь вид
61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028.
Дополненное сообщение будет содержать 16 * n слов для некоторого n > 0. Дополненное сообщение рассматривается как последовательность из n блоков M(1), M(2), первые символы (или биты) сообщения.
5. Используемые функции и константы
В SHA-1 используется последовательность логических функций f(0), f(1). f(79). Каждая f(t), 0 32 , F — нелинейная функция,
Рис. 1. Алгоритм вычисления дайджеста SCH1 [5]
Методы, представленные в разделах 6.1 и 6.2, выдают идентичные дайджесты сообщения. Хотя, использование метод 2 позволяет сэкономить 64 32-битовых слов в памяти, он вероятно удлинит время исполнения из-за усложнения вычисления адресов для < Wа[t] >на шаге (c). Существуют другие методы вычисления, которые дают идентичные результаты.
6.1. Метод 1
Дайджест сообщения вычисляется с использованием дополненного сообщения, как это описано в разделе 4. Вычисление описано для случая двух буферов, каждый из которых содержит пять 32-битных слов, и последовательность из восьмидесяти 32-битовых слов. Слова первого 5-словного буфера помечены как A,B,C,D,E. Слова второго 5-словного буфера помечены как H0, H1, H2, H3, H4. Слова массива из 80 слов помечены, как W(0), W(1). W(79). Используется также буфер для одного слова TEMP.
Чтобы сгенерировать дайджест сообщения, блоки из 16-слов M(1), M(2). M(n), определенные в разделе 4, обрабатываются последовательно. Обработка каждого M(i) включает в себя 80 шагов.
Прежде чем обрабатывать какой-либо блок, все H инициализируются следующим образом: в hex-представлении:
H0 = 67452301 H1 = EFCDAB89 H2 = 98BADCFE H3 = 10325476 H4 = C3D2E1F0.
Теперь обрабатываются M(1), M(2), . , M(n). Чтобы обработать M(i), мы выполняем следующее:
- Разделяем M(i) на 16 слов W(0), W(1), . , W(15), где W(0) является самым левым словом.
- Для t = 16 до 79 пусть
W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)).
TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t); E = D; D = C; C = S30(B); B = A; A = TEMP;
После обработки M(n), дайджест сообщения является 160-битовой строкой, в виде 5 слов:
H0 H1 H2 H3 H4.
6.2 Метод 2
Предыдущий метод предполагает, что последовательность W(0), . , W(79) представляет собой массив из 80 32-битных слов. Это эффективно с точки зрения минимизации времени вычисления, так как адреса W(t-3), . ,W(t-16) на этапе (b) легче вычислять. Когда имеется дефицит памяти, можно для < W(t) >организовать кольцевой буфер, который может использовать массив из 16 32-битных слов W[0], . W[15]. В этом случае в hex-формате получим: MASK = 0000000F. Затем обрабатываем M(i) следующим образом:
- Делим M(i) на 16 слов W[0], . , W[15], где W[0] — самое левое слово.
- Пусть A = H0, B = H1, C = H2, D = H3, E = H4.
- Для t = 0 до 79 выполнить
s = t AND MASK; если (t >= 16) W[s] = S^1(W[(s + 13) AND MASK] XOR W[(s + 8) AND MASK] XOR W[(s + 2) AND MASK] XOR W[s]); TEMP = S^5(A) + f(t;B,C,D) + E + W[s] + K(t); E = D; D = C; C = S^30(B); B = A; A = TEMP;
7. C Code
Ниже представлена реализация SHA-1 на C. Раздел 7.1 содержит файл заголовков, 7.2 — код C, и 7.3 — тестовый драйвер.
7.1. .h file
/* * sha1.h * * Описание: * Это файл заголовков для программы, которая реализует SHA1, как он определен в FIPS PUB 180-, опубликованном 17 апреля 1995. * * Многие имена переменных в этой программе, особенно односимвольные имена, * взяты из более ранних публикаций. * * Please read the file sha1.c for more information. * */ #ifndef _SHA1_H_ #define _SHA1_H_ #include /* * Если у вас нет стандартного ISO файла заголовков stdint.h, тогда вы должны * typdef следующее: * имя значение * uint32_t unsigned 32 bit целое * uint8_t unsigned 8 bit целое (т.e., unsigned char) * int_least16_t целое of >= 16 bits * */ #ifndef _SHA_enum_ #define _SHA_enum_ enum < shaSuccess = 0, shaNull, /* Null pointer parameter */ shaInputTooLong, /* входные данные слишком длины */ shaStateError /* called Input after Result */ >; #endif #define SHA1HashSize 20 * Эта структура будет содержать контекстную информацию для хэш-операций SHA-1 */ typedef struct SHA1Context < uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Дайджест сообщения */ uint32_t Length_Low; /* Длина сообщения в битах */ uint32_t Length_High; /* Длина сообщения в битах */ /* Индекс массива блока сообщения */ int_least16_t Message_Block_Index; uint8_t Message_Block[64]; /* 512-битовые блоки сообщения */ int Computed; /* дайджест вычислен? */ int Corrupted; /* Дайджест сообщения поврежден? */ >SHA1Context; /* * Прототипы функций */ int SHA1Reset( SHA1Context *); int SHA1Input( SHA1Context *, const uint8_t *, unsigned int); int SHA1Result( SHA1Context *, uint8_t Message_Digest[SHA1HashSize]); #endif
7.2. .c file
/* * sha1.c * * Описание: * этот файл реализует алгоритм SHA1, как это определено в * FIPS PUB 180-1 April 17, 1995. * * Алгоритм SHA-1, формирует 160-битовый дайджест сообщения для заданного информационного потока. * Чтобы найти сообщение с тем же дайджестом, должно потребоваться около 2n шагов * и * 2(n/2), чтобы найти два сообщения с одним и тем же дайджестом, * где n размер дайджеста в бит. Следовательно, этот алгоритм может использоваться в качестве идентификатора сообщения. * * Соображения о переносимости: * SHA-1 определен в терминах 32-битных "слов". этот код использует * (включенный через "sha1.h" чтобы определить 32 и 8 битовые операции с целыми без знака * Если ваш C-компилятор не поддерживает операции с 32-битовыми целыми без знака, этот код не применим. * * Предостережения: * SHA-1 спроектирован для работы с длиной сообщений меньше чем 264 бит. Хотя SHA-1 позволяет генерировать дайджесты сообщений * для сообщений с любым числом бит меньше чем 264, эта реализация * работает с сообщениями, длина которых кратна 8-битным символам. * */ * /
#include "sha1.h" #include "sha1.h" /* Определяем макро циклического сдвига SHA1 */ #define SHA1CircularShift(bits,word) \ (((word) > (32-(bits)))) /* Local Function Prototyptes */ void SHA1PadMessage(SHA1Context *); void SHA1ProcessMessageBlock(SHA1Context *);
/* * SHA1Reset * * Описание: * Эта функция будет инициализировать SHA1Context при подготовке к * вычислению нового дайджеста сообщения SHA1. * * Параметры: * context: [in/out] * Сброс контекста. * * Возвращает: * sha Error Code. * */ int SHA1Reset(SHA1Context *context) < if (!context) < return shaNull; >context->Length_Low = 0; context->Length_High = 0; context->Message_Block_Index = 0; context->Intermediate_Hash[0] = 0x67452301; context->Intermediate_Hash[1] = 0xEFCDAB89; context->Intermediate_Hash[2] = 0x98BADCFE; context->Intermediate_Hash[3] = 0x10325476; context->Intermediate_Hash[4] = 0xC3D2E1F0; context->Computed = 0; context->Corrupted = 0; return shaSuccess; >
/* * SHA1Result * * Описание: * Эта функция занесет 160-битовый дайджест сообщения в массив * Message_Digest, заданный при запросе. * Заметим: Первый октет хэша записывается в 0-ой элемент, * последний октет хэша заносится в 19-ый элемент. * * Параметры: * context: [in/out] * Контекст, который используется при вычислении хэша SHA-1. * Message_Digest: [out] * Куда заносится вычисленный дайджест. * * Возвращает: * sha Error Code. * */ int SHA1Result( SHA1Context *context, uint8_t Message_Digest[SHA1HashSize]) < int i; если (!context || !Message_Digest) < return shaNull; >if (context->Corrupted) < return context->Corrupted; > if (!context->Computed) < SHA1PadMessage(context); for(i=0; iMessage_Block[i] = 0; > context->Length_Low = 0; /* и clear length */ context->Length_High = 0; context->Computed = 1; > for(i = 0; i < SHA1HashSize; ++i) < Message_Digest[i] = context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); > return shaSuccess; >
/* * SHA1Input * * Описание: * Эта функция воспринимает массив октетов в качестве следующей части сообщения. * * Параметры: * context: [in/out] * Контекст SHA чтобы обновить массив сообщения * message_array: [in] * Массив символов представляющих следующую часть сообщения. * length: [in] * Длина сообщения в message_array * * Возвращает: * sha Error Code. * */
int SHA1Input( SHA1Context *context, const uint8_t *message_array, unsigned length) < if (!length) < return shaSuccess; >if (!context || !message_array) < return shaNull; >if (context->Computed) < context->Corrupted = shaStateError; return shaStateError; > if (context->Corrupted) < return context->Corrupted; > while(length-- && !context->Corrupted) < context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF); context->Length_Low += 8; if (context->Length_Low == 0) < context->Length_High++; if (context->Length_High == 0) < /* Message is too long */ context->Corrupted = 1; > > if (context->Message_Block_Index == 64) < SHA1ProcessMessageBlock(context); >message_array++; > return shaSuccess; > /* * SHA1ProcessMessageBlock * * Описание: * Эта функция будет обрабатывать следующие 512 бит сообщения, записанные в массиве Message_Block. * * * */
void SHA1ProcessMessageBlock(SHA1Context *context) < const uint32_t K[] = < /* Константы заданные в SHA-1 */ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 >; int t; /* Счетчик циклов */ uint32_t temp; /* Temporary word value */ uint32_t W[80]; /* Последовательность слов */ uint32_t A, B, C, D, E; /* Буферы слов */ /* * Инициализируем первые 16 слов в массиве W */ for(t = 0; t < 16; t++) < W[t] = context->Message_Block[t * 4] Message_Block[t * 4 + 1] Message_Block[t * 4 + 2] Message_Block[t * 4 + 3]; > for(t = 16; t < 80; t++) < W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); >A = context->Intermediate_Hash[0]; B = context->Intermediate_Hash[1]; C = context->Intermediate_Hash[2]; D = context->Intermediate_Hash[3]; E = context->Intermediate_Hash[4]; for(t = 0; t < 20; t++) < temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; >for(t = 20; t < 40; t++) < temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; >for(t = 40; t < 60; t++) < temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; >for(t = 60; t < 80; t++) < temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; >context->Intermediate_Hash[0] += A; context->Intermediate_Hash[1] += B; context->Intermediate_Hash[2] += C; context->Intermediate_Hash[3] += D; context->Intermediate_Hash[4] += E; context->Message_Block_Index = 0; > /* * SHA1PadMessage *
* Описание: * В соответствии со стандартом, сообщение должно быть дополнено до позиции, кратной * 512 бит. Первый бит заполнителя должен быть равен '1'. Последние 64 бита * характеризуют длину исходного сообщения. Все промежуточные биты должны быть нулевыми. эта функция дополнит сообщение * согласно правилам заполнения массива Message_Block. * Она вызовет также функцию ProcessMessageBlock. * Когда возвращается код, предполагается, что дайджест был вычислен. * * Параметры: * context: [in/out] * The context to pad * ProcessMessageBlock: [in] * The appropriate SHA*ProcessMessageBlock function * */ void SHA1PadMessage(SHA1Context *context) < /* Проверяем, не является ли данный блок сообщения слишком мал, чтобы хранить * биты заполнителя и длины. Если это так, мы дополним блок, обработаем его * и затем продолжим дополнение во второй блок. */ if (context->Message_Block_Index > 55) < context->Message_Block[context->Message_Block_Index++] = 0x80; while(context->Message_Block_Index < 64) < context->Message_Block[context->Message_Block_Index++] = 0; > SHA1ProcessMessageBlock(context); while(context->Message_Block_Index < 56) < context->Message_Block[context->Message_Block_Index++] = 0; > > else < context->Message_Block[context->Message_Block_Index++] = 0x80; while(context->Message_Block_Index < 56) < context->Message_Block[context->Message_Block_Index++] = 0; > > /* Запоминаем длину сообщения в виде последних 8 октетов */ context->Message_Block[56] = context->Length_High >> 24; context->Message_Block[57] = context->Length_High >> 16; context->Message_Block[58] = context->Length_High >> 8; context->Message_Block[59] = context->Length_High; context->Message_Block[60] = context->Length_Low >> 24; context->Message_Block[61] = context->Length_Low >> 16; context->Message_Block[62] = context->Length_Low >> 8; context->Message_Block[63] = context->Length_Low; SHA1ProcessMessageBlock(context); >
7.3 Тестовый драйвер
Ниже приведен код основной программы тестового драйвера для проверки кода sha1.c.
/* * sha1test.c * * Описание: * Этот файл служит для проверки кода SHA-1, выполняющего три теста, описанных в FIPS PUB 180-1 плюс один, который называется * SHA1Input и имеет длину является кратную 512 бит, плюс проверки нескольких ошибок. * */ #include #include #include #include "sha1.h" /* Определяем образцы для тестирования */ #define TEST1 "abc" #define TEST2a "abcdbcdecdefdefgefghfghighijhi" #define TEST2b "jkijkljklmklmnlmnomnopnopq" #define TEST2 TEST2a TEST2b #define TEST3 "a" #define TEST4a "01234567012345670123456701234567" #define TEST4b "01234567012345670123456701234567" /* an exact multiple of 512 bits */ #define TEST4 TEST4a TEST4b char *testarray[4] = < TEST1, TEST2, TEST3, TEST4 >; long int repeatcount[4] = < 1, 1, 1000000, 10 >; char *resultarray[4] = < "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D", "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1", "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F", "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52" >; int main() < SHA1Context sha; int i, j, err; uint8_t Message_Digest[20]; /* * Perform SHA-1 tests */ for(j = 0; j < 4; ++j) < printf( "\nTest %d: %d, '%s'\n", j+1, repeatcount[j], testarray[j]); err = SHA1Reset(&sha); if (err) < fprintf(stderr, "SHA1Reset Error %d.\n", err ); break; /* out of for j loop */ >for(i = 0; i < repeatcount[j]; ++i) < err = SHA1Input(&sha, (const unsigned char *) testarray[j], strlen(testarray[j])); if (err) < fprintf(stderr, "SHA1Input Error %d.\n", err ); break; /* out of for i loop */ >> err = SHA1Result(&sha, Message_Digest); if (err) < fprintf(stderr, "SHA1Result Error %d, could not compute message digest.\n", err ); >else < printf("\t"); for(i = 0; i < 20 ; ++i) < printf("%02X ", Message_Digest[i]); >printf("\n"); > printf("Should match:\n"); printf("\t%s\n", resultarray[j]); > /* Тест возвращает некоторые ошибки */ err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1); printf ("\nError %d. Should be %d.\n", err, shaStateError ); err = SHA1Reset(0); printf ("\nError %d. Should be %d.\n", err, shaNull ); return 0; > >
Ссылки
[1] «Secure Hash Standard», United States of American, National Institute of Science и Technology, Federal Information Processing Standard (FIPS) 180-1, April 1993.
[2] «The MD4 Message Digest Algorithm,» Advances in Cryptology — CRYPTO ’90 Proceedings, Springer-Verlag,1991, pp. 303-311.
[3] Rivest, R., «The MD4 Message-Digest Algorithm», RFC1320, April 1992.
[4] [RFC 1321] Rivest, R., «The MD5 Message-Digest Algorithm», RFC1321, April 1992.
[5] Eastlake, D., Crocker, S. и J. Schiller, «Randomness Requirements for Security», RFC 1750, December 1994.