Пошагово объясняем, как работает алгоритм хеширования SHA-2 (SHA-256)

Введение в SHA256

SHA256 — это алгоритм, подразделенный под SHA-2.
SHA-2, название происходит от аббревиатуры Secure Hash Algorithm 2 (англ .: Secure Hash Algorithm 2), стандарт алгоритма криптографической хеш-функции, разработанный Агентством национальной безопасности, является одним из алгоритмов SHA, это SHA-1 Преемник.

В соответствии с SHA-2 его можно разделить на шесть различных стандартов алгоритмов.

В том числе: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256.

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

Возвращаясь к SHA256, прямо скажем, это хеш-функция.

Хеш-функции, также известные как алгоритмы хеширования, представляют собой метод создания небольших цифровых «отпечатков пальцев» из любых данных. Хеш-функция сжимает сообщение или данные в дайджест, уменьшая объем данных и фиксируя формат данных. Эта функция перемешивает данные и воссоздает отпечаток пальца, называемый хэш-значением (или хэш-значением). Значение хеша обычно представлено короткой цепочкой случайных букв и цифр.

Для сообщений любой длины SHA256 генерирует 256-битное хеш-значение, называемое дайджестом сообщения.

Это резюме эквивалентно массиву длиной 32 байта, обычно представленному шестнадцатеричной строкой длиной 64

Давайте посмотрим на пример:

Станьте программистом блокчейна на 100 дней, и дядя Красной Армии ведет нас, сражаясь!

В этом предложении значение хеш-функции, полученное после хеш-функции SHA256:

A7FCFC6B5269BDCCE571798D618EA219A68B96CB87A0E21080C2E758D23E4CE9

Нашел один здесьSHA256 онлайн-инструмент проверки, Может использоваться для проверки результата хеширования SHA256, а также для проверки правильности кода SHA256. Это очень удобно для использования, вы можете почувствовать это.

Что такое хэш-функция?

Три основных цели хэш-функций:

  • Детерминировано шифровать данные (такой вид шифрования всегда создает одно и то же зашифрованное значение для одного и того же текстового значения);
  • Принимать ввод любой длины, а выводить результат фиксированной длины;
  • Изменять данные необратимо. Ввод нельзя получить из вывода.

SHA-2 выполняет их в полной мере. Если хотите узнать больше о хэш-функциях, на Хабре есть несколько подходящих публикаций. Например, статьи «Что такое хэширование? Под капотом блокчейна» и «Хэш-алгоритмы».

Подробное объяснение принципа SHA256

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

2.1 Постоянная инициализация

8 начальных хеш-значений и 64 хеш-константы используются в алгоритме SHA256

Среди них алгоритм SHA2568 начальных хеш-значенийследующее:

h0 := 0x6a09e667 h1 := 0xbb67ae85 h2 := 0x3c6ef372 h3 := 0xa54ff53a h4 := 0x510e527f h5 := 0x9b05688c h6 := 0x1f83d9ab h7 := 0x5be0cd19

Эти начальные значения получают, взяв первые 32 бита дробной части квадратного корня из первых 8 простых чисел (2, 3, 5, 7, 11, 11, 13, 17 и 19) в натуральные числа

Например, 2–√ 2 Дробная часть составляет около 0,414213562373095048, и

0.414213562373095048≈6∗16−1+a∗16−2+0∗16−3+… 0.414213562373095048 ≈ 6 ∗ 16 − 1 + a ∗ 16 − 2 + 0 ∗ 16 − 3 + . . . Следовательно, дробная часть квадратного корня из простого числа 2 составляет первые 32 бита и соответствует0x6a09e667

В алгоритме SHA256 используется64 константыследующее:

428a2f98 71374491 b5c0fbcf e9b5dba5 3956c25b 59f111f1 923f82a4 ab1c5ed5 d807aa98 12835b01 243185be 550c7dc3 72be5d74 80deb1fe 9bdc06a7 c19bf174 e49b69c1 efbe4786 0fc19dc6 240ca1cc 2de92c6f 4a7484aa 5cb0a9dc 76f988da 983e5152 a831c66d b00327c8 bf597fc7 c6e00bf3 d5a79147 06ca6351 14292967 27b70a85 2e1b2138 4d2c6dfc 53380d13 650a7354 766a0abb 81c2c92e 92722c85 a2bfe8a1 a81a664b c24b8b70 c76c51a3 d192e819 d6990624 f40e3585 106aa070 19a4c116 1e376c08 2748774c 34b0bcb5 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3 748f82ee 78a5636f 84c87814 8cc70208 90befffa a4506ceb bef9a3f7 c67178f2

Подобно 8 начальным значениям хеша, эти константы являются первыми 64 простыми числами в натуральном числе (2,3,5,7,11,13,17,19,23,29,31,37,41,43,47, 53,59,61,67,71,73,79,83,89,97 …) дробная часть корня куба происходит от первых 32 битов.

2.2 Предварительная обработка информации (предварительная обработка)

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

Предварительная обработка информации делится на два этапа:Дополнительные биты заполнениясДополнительная длина

STEP1: дополнительные биты заполнения

Заполните конец сообщения, чтобы оставшаяся часть длины сообщения после модуля 512 составляла 448

Заполнение выполняется таким образом, что первый бит заполняется 1, а затем оба заполняются 0, пока длина не соответствует модулю 512, а остаток равен 448.

Следует отметить, что информация должна быть дополнена, то есть, даже если длина удовлетворяла остатку после того, как по модулю 512 было 448, биты дополнения также должны выполняться, чтобы заполнить 512 бит.

Следовательно, заполнение должно заполнять как минимум один бит и до 512 бит.

пример: Используйте сообщение «abc» в качестве примера, чтобы показать процесс заполнения.

соответствует а, б, вКод ASCII97, 98, 99 соответственно

Итак, двоичный код исходной информации: 01100001 01100010 01100011

Первый шаг для заполнения позиции, сначала заполните «1»: 0110000101100010 01100011 1

На втором этапе заполнения заполняется 423 «0»: 01100001 01100010 01100011 10000000 00000000… 00000000

Данные после завершения битового дополнения выглядят следующим образом (в шестнадцатеричном формате для ознакомления):

61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Почему 448?

Поскольку после первого этапа предварительной обработки, на втором этапе будут добавлены 64-разрядные данные, указывающие длину исходного сообщения. И 448 + 64 = 512, что просто является полной структурой.

STEP2: дополнительное значение длины

Дополнительное значение длины заключается в добавлении информации о длине исходных данных (сообщение перед первым этапом заполнения) к сообщению после выполнения операции заполнения.

Оригинальный текст, данный в Википедии:append length of message (before pre-processing), in bits, as 64-bit big-endian integer

SHA256 использует 64-битные данные для представления длины исходного сообщения.

Следовательно, длина сообщения, рассчитанная SHA256, должна быть меньше 264 2 6 4 Конечно, в большинстве случаев это достаточно велико.

Метод кодирования информации о длине — это 64-разрядное целое число с прямым порядком байтов

наBig endianЗначение дано в конце статьи

Теперь вернемся к примеру, сообщение «abc», 3 символа, занимает 24 бита.

Поэтому после операции дополнения длины все сообщение становится следующим (шестнадцатеричный формат)

61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018

2.3 Логические операции

Все операции, выполняемые в хэш-функции SHA256, являются логическими битовыми операциями.

Включая следующие логические функции:

Ch(x,y,z)=(x∧y)⊕(¬x∧z) C h ( x , y , z ) = ( x ∧ y ) ⊕ ( ¬ x ∧ z )

Ma(x,y,z)=(x∧y)⊕(x∧z)⊕(y∧z) M a ( x , y , z ) = ( x ∧ y ) ⊕ ( x ∧ z ) ⊕ ( y ∧ z )

Σ0(x)=S2(x)⊕S13(x)⊕S22(x) Σ 0 ( x ) = S 2 ( x ) ⊕ S 13 ( x ) ⊕ S 22 ( x )

Σ1(x)=S6(x)⊕S11(x)⊕S25(x) Σ 1 ( x ) = S 6 ( x ) ⊕ S 11 ( x ) ⊕ S 25 ( x )

σ0(x)=S7(x)⊕S18(x)⊕R3(x) σ 0 ( x ) = S 7 ( x ) ⊕ S 18 ( x ) ⊕ R 3 ( x )

σ1(x)=S17(x)⊕S19(x)⊕R10(x) σ 1 ( x ) = S 17 ( x ) ⊕ S 19 ( x ) ⊕ R 10 ( x )

где:

логическая операциясмысл
∧ ∧Побитовое И
¬ ¬Побитовое «дополнение»
⊕ ⊕Побитовый XOR
Sn S nСдвиг вправо n бит
Rn R nПовернуть вправо на n бит

2.4 Рассчитать дайджест сообщения

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

Первое: разбить сообщение на 512-битные блоки

(break message into 512-bit chunks)

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

Начальное значение 256-битного дайджеста, H0, вычисляется через первый блок данных, чтобы получить H1, который является первой итерацией.

H1 получает H2 через второй блок данных, …, обрабатывает его по очереди и, наконец, получает Hn, который является окончательным дайджестом 256-битного сообщения

Используйте отображение для каждой итерации Map(Hi−1)=Hi M a p ( H i − 1 ) = H i Означает, что итерация может быть отображена более ярко как:

256 бит на картинкеHiОписано 8 маленьких блоков, это потому, что наименьшая арифметическая единица в алгоритме SHA256 называется «Слово» (Word), слово составляет 32 бита.

Кроме того, в первой итерации начальное значение карты устанавливается равным 8 начальным значениям введенного ранее хеша, как показано на следующем рисунке:

Следующее начинает вводить содержание каждой итерации, то есть отображение Map(Hi−1)=Hi M a p ( H i − 1 ) = H i Конкретный алгоритм

ШАГ 1: Построить 64 слова

break chunk into sixteen 32-bit big-endian words w[0], …, w[15]

Для каждого блока разложите блок на 16 32-битных слов с прямым порядком байтов, обозначаемых как w [0],…, w [15]

Другими словами, первые 16 слов непосредственно разлагаются из i-го блока сообщения.

Остальные слова получаются по следующей итерационной формуле:

Wt=σ1(Wt−2)+Wt−7+σ0(Wt−15)+Wt−16 W t = σ 1 ( W t − 2 ) + W t − 7 + σ 0 ( W t − 15 ) + W t − 16

ШАГ 2: 64 цикла

карта Map(Hi−1)=Hi M a p ( H i − 1 ) = H i Содержит 64 цикла шифрования

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

Каждый цикл шифрования может быть описан следующим рисунком:

На рисунке 8 слов ABCDEFGH обновлены в соответствии с определенными правилами, среди которых

Синие квадраты — это заранее определенные нелинейные логические функции, которые были выложены выше.

Квадрат красного поля представляет мод 232 2 32 Кроме того, два числа складываются вместе, если результат больше 232 2 32 , Вы должны разделить на 232 2 32 И найти остаток.

Начальные значения ABCDEFGH в начале Hi−1(0),Hi−1(1),…,Hi−1(7) H i − 1 ( 0 ) , H i − 1 ( 1 ) , . . . , H i − 1 ( 7 )

Kt — т-й ключ, соответствующий 64 константам, которые мы упомянули выше

Wt — это t-е слово, сгенерированное в этом блоке. Исходное сообщение разбивается на 512-битные блоки фиксированной длины, и для каждого блока генерируется 64 слова. Восемь слов ABCDEFGH циклически шифруются путем повторения цикла n раз.

Восемь символов, сгенерированных последним циклом, являются хеш-строкой, соответствующей i-му блоку. Hi H i

Это изменение завершает все введения в алгоритм SHA256

Приложение:

Python Sha256 используется в некоторых из самых популярных протоколов шифрования и аутентификации, таких как:

  • href=»https://en.wikipedia.org/wiki/Secure_Sockets_Layer»>SSL: href=»https://en.wikipedia.org/wiki/Secure_Sockets_Layer»>SSL: secure sockets layer
  • TLS: безопасность транспортного уровня
  • IPSec: безопасность интернет-протокола
  • SSH: secure shell

Sha256 также используется в unix и linux для защиты паролей с помощью хэша.

SHA256 алгоритм псевдокода

Теперь мы можем объединить псевдокод алгоритма SHA256 и прочесать все вышеперечисленные шаги:

Note: All variables are unsigned 32 bits and wrap modulo 232 when calculating Initialize variables (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): h0 := 0x6a09e667 h1 := 0xbb67ae85 h2 := 0x3c6ef372 h3 := 0xa54ff53a h4 := 0x510e527f h5 := 0x9b05688c h6 := 0x1f83d9ab h7 := 0x5be0cd19 Initialize table of round constants (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311): k[0..63] := 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 Pre-processing: append the bit ‘1’ to the message append k bits ‘0’, where k is the minimum number >= 0 such that the resulting message length (in bits) is congruent to 448(mod 512) append length of message (before pre-processing), in bits, as 64-bit big-endian integer Process the message in successive 512-bit chunks: break message into 512-bit chunks for each chunk break chunk into sixteen 32-bit big-endian words w[0..15] Extend the sixteen 32-bit words into sixty-four 32-bit words: for i from 16 to 63 s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor(w[i-15] rightshift 3) s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor(w[i-2] rightshift 10) w
:= w[i-16] + s0 + w[i-7] + s1 Initialize hash value for this chunk: a := h0 b := h1 c := h2 d := h3 e := h4 f := h5 g := h6 h := h7 Main loop: for i from 0 to 63 s0 := (a rightrotate 2) xor (a rightrotate 13) xor(a rightrotate 22) maj := (a and b) xor (a and c) xor(b and c) t2 := s0 + maj s1 := (e rightrotate 6) xor (e rightrotate 11) xor(e rightrotate 25) ch := (e and f) xor ((not e) and g) t1 := h + s1 + ch + k + w h := g g := f f := e e := d + t1 d := c c := b b := a a := t1 + t2 Add this chunk’s hash to result so far: h0 := h0 + a h1 := h1 + b h2 := h2 + c h3 := h3 + d h4 := h4 + e h5 := h5 + f h6 := h6 + g h7 := h7 + h Produce the final hash value (big-endian): digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

Предисловие

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

Инструменты JAVA

package cn.hengyumo.humor.utils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * HeaUtil * Hash encryption algorithm * Алгоритм шифрования хэша: MD5, SHA-1, SHA-256, HMAC-SHA-1, HMAC-SHA-256 * Необходимо импортировать пакет org.apache.commons.codec * * @author hengyumo * @version 1.0 * @since 2019/11/12 */ @SuppressWarnings(«WeakerAccess») public class HeaUtil { /** * шифрование md5 * * @param текстовое содержимое * @return сводка дайджеста * @throws NoSuchAlgorithmException e */ public static String md5(String text) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(«MD5»); byte[] bytes = messageDigest.digest(text.getBytes()); return Hex.encodeHexString(bytes); } /** * шифрование sha1 * * @param текстовое содержимое * @return сводка дайджеста * @throws NoSuchAlgorithmException e */ public static String sha1(String text) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(«SHA-1»); byte[] bytes = messageDigest.digest(text.getBytes()); return Hex.encodeHexString(bytes); } /** * шифрование sha256 * * @param текстовое содержимое * @return сводка дайджеста * @throws NoSuchAlgorithmException e */ public static String sha256(String text) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(«SHA-256»); byte[] bytes = messageDigest.digest(text.getBytes()); return Hex.encodeHexString(bytes); } /** * шифрование hmac-sha1 * * @param текстовое содержимое * ключ @param key * * @ вернуть зашифрованный текст * @throws Exception e */ public static String hmacSha1(String text, String key) throws Exception { SecretKeySpec sk = new SecretKeySpec(key.getBytes(), «HmacSHA1»); return hmacSha1(text, sk); } /** * шифрование hmac-sha1 * * @param текстовое содержимое * @param sk ключ * * @ вернуть зашифрованный текст * @throws Exception e */ public static String hmacSha1(String text, SecretKeySpec sk) throws Exception { Mac mac = Mac.getInstance(«HmacSHA1»); mac.init(sk); byte[] rawHmac = mac.doFinal(text.getBytes()); return new String(Base64.encodeBase64(rawHmac)); } /** * Создать ключ HmacSha1 * * @param key строка ключа * @return SecretKeySpec */ public static SecretKeySpec createHmacSha1Key(String key) { return new SecretKeySpec(key.getBytes(), «HmacSHA1»); } /** * шифрование hmac-sha256 * * @param текстовое содержимое * ключ @param key * * @ вернуть зашифрованный текст * @throws Exception e */ public static String hmacSha256(String text, String key) throws Exception { SecretKeySpec sk = new SecretKeySpec(key.getBytes(), «HmacSHA256»); return hmacSha1(text, sk); } /** * шифрование hmac-sha256 * * @param текстовое содержимое * @param sk ключ * * @ вернуть зашифрованный текст * @throws Exception e */ public static String hmacSha256(String text, SecretKeySpec sk) throws Exception { Mac mac = Mac.getInstance(«HmacSHA256»); mac.init(sk); byte[] rawHmac = mac.doFinal(text.getBytes()); return new String(Base64.encodeBase64(rawHmac)); } /** * Сгенерировать ключ HmacSha256 * * @param key строка ключа * @return SecretKeySpec */ public static SecretKeySpec createHmacSha256Key(String key) { return new SecretKeySpec(key.getBytes(), «HmacSHA256»); } /** * Тестовое задание * * @param args args */ public static void main(String[] args) throws Exception { String s = «123456789 не нравится, не нравится»; System.out.println(md5(s)); System.out.println(sha1(s)); System.out.println(sha256(s)); String k = «»; System.out.println(hmacSha1(s, k)); s = «aeqnfoavneornqoenr1, но я не могу понять ситуацию на юге 010jownfasdfqijqor»; System.out.println(hmacSha1(s, k)); SecretKeySpec sk1 = createHmacSha1Key(k); System.out.println(hmacSha1(s, sk1)); SecretKeySpec sk256 = createHmacSha256Key(k); System.out.println(hmacSha256(s, sk256)); } }
Вывод

d415ffe55bf2e18b9e059be4ab371fe7 15b03a4189d24ca3459e199bbf8de7fc3e4d68f3 e32b84b738416e91198112a57d295ba685a40e55bb114725e8a444efd53d5a01 ck66ZAkPEh+19UIgnX775N3nLyc= WVJAs/+6OlwkzM1ZEK+t8iMgtyc= WVJAs/+6OlwkzM1ZEK+t8iMgtyc= E1sXoiPtnjzMiDRagp08Lt3gBKXE/EU+nLJZpy8hURc=

Замечания

Используйте необходимость импорта пакета maven или jar

<!— https://mvnrepository.com/artifact/commons-codec/commons-codec —> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.12</version> </dependency>

Рейтинг
( 1 оценка, среднее 5 из 5 )
Понравилась статья? Поделиться с друзьями:
Для любых предложений по сайту: [email protected]