Протокол WireGuard позволяет создать защищенный сетевой туннель на третьем уровне модели ВОС между двумя узлами с помощью протокола передачи сообщений UDP. Он использует криптографическое квитирование, пересылка сообщений или сигналов, выдаваемых в ответ на принятые сообщения для осуществления взаимной аутентификации, согласования ключей и обеспечения прямой секретности. Защита информации, передаваемой в инкапсулированных IP-пакетах через туннели WireGuard, осуществляется с использованием аутентифицированного шифрования с присоединенными данными (Authenticated Encryption with Associated Data, далее AEAD).
Каждый узел может начать сессию после отправки сообщения о квитировании и приема ответного сообщения. В этом протоколе не существует строго закрепленных ролей клиента и сервера как у других протоколов туннелирования. Узел, который намерен начать сессию, называют инициатором, а узел, с которым устанавливают соединение, – ответчиком.
Обе стороны генерируют одноразовые пары ключей Curve25519 в процессе квитирования. Соответствующие закрытые ключи удаляются после окончания квитирования и таким образом гарантируют защищенность сессии. Каждая сессия имеет фиксированное время жизни и ограниченное количество сообщений, которые могут быть переданы. В случае если узлам требуется больше времени для работы или им нужно отправить больше сообщений, то им требуется перейти на новые сессионные ключи. Важно отметить, что периодическая смена ключей значительно снижает возможность их компрометации.
Сетевой интерфейс WireGuard (далее wg0) может подключаться к множеству узлов. Для гарантирования того, что IP-трафик направлен в нужный узел, существует политика маршрутизации криптоключей. В ней узлы ассоциируются с определенным набором доступных ему IP-адресов. Локальный трафик, поступающий на wg0, будет отправлен только в том случае, если IP-адрес назначения доступен для данного узла. А входящий трафик будет принят, если IP-адрес источника расшифрованного IP-пакета, содержится в списке доступных IP-адресов у аутентифицированного узла.
Потоковые шифры семейства Salsa20
Salsa20 – это семейство 256-битных потоковых шифров, работа которых основывается на использовании короткого секретного ключа для шифрования передаваемых сообщений между отправителем и получателем.
Отправитель и получатель шифруют сообщения с помощью функции преобразования, суть работы которой заключается в использовании длинной цепочки простых операций с 32-битными словами:
32-битное суммирование, представленное в виде, где a и b – два 32-битных слова.
32-битное исключающее ИЛИ, представленное в виде, где a и b – два 32-битных слова.
32-битное смещение, представленное в виде, где a – 32-битное слов, а b – определенное количество бит, на которое происходит смещение.
Операции Salsa20/r:
где a, b, c, d – 32-битные слова.
Работа Salsa20 заключается в преобразовании 256-битного ключа и 64-битного одноразового кода в 270-байтный поток, с помощью которого будет происходить шифрование b-байтного открытого текста, путем сложения его по модулю 2 с первыми b байтами потока и отбрасывания оставшейся его части. Дешифрование происходит по тому же алгоритму.
Сам поток представлен в виде 64-байтных (512-битных) блоков. Каждый блок представляет из последовательность шестнадцатеричных символов, составленную из ключа, одноразового кода и 64-битного номера блока. Между собой блоки не связываются, поэтому их вычисление может быть организовано параллельно.
Ядро Salsa20 представлено в виде матрицы, состоящей из 16 слов: константы 0x6170865, первых четырех ключевых слов, константы 0x3320646e, двух слов одноразового кода, двух слов блокового счетчика, константы 0x79622d32, оставшихся четырех ключевых слов и константы 0x6b206574.
Рассмотрим пример, где начальная матрица Salsa20 выглядит следующим образом:
Диагональные константы одинаковы для каждого блока, каждого одноразового кода и для каждого 32-байтного ключа. После получения данного массива происходит изменение каждого под-диагонального слова по следующему алгоритму: сложение диагонального и над-диагонального слов, смещение на 7 бит влево и сложение по модулю 2 с под-диагональными словами.
Пример (первый столбец):
1) 61707865 + 18171615 = 79878E7A = 01111001100001111000111001111010.
2) 11000011110001110011110100111100 = C3C73D3C.
3) C3C73D3C xor 100F030D = D3C83331.
Далее изменяются все под-под-диагональные слова следующим образом: суммирование диагональных и под-диагональных слов, смещение на 9 бит влево и сложение по модулю 2 с под-под-диагональными словами.
Пример (первый столбец):
1) D3C83331 + 61707865 = 3538AB96 = 00110101001110001010101110010110.
2) 01110001010101110010110001101010 = 71572C6A.
3) 71572C6A xor 00000007 = 71572C6D.
На следующем шаге происходит суммирование под-диагонального и под-под-диагонального слов, смещением влево на 13 бит и сложение по модулю 2 с над-диагональным словом.
Пример (второй столбец):
1) 71572C6D + D3C83331 = 451F5F9E = 01000101000111110101111110011110.
2) 11101011111100111100100010100011 = EBF3C8A3.
3) EBF3C8A3 xor 18171615 = F3E4DEB6.
Затем осуществляется суммирование над-диагонального и под-под-диагонального слова, смещением влево на 18 бит и сложение по модулю 2 с диагональным словом.
Пример (первый столбец):
1) F3E4DEB6 + 71572C6D = 653C0B23 = 01100101001111000000101100100011.
2) 00101100100011011001010011110000= 2C8D94F0.
3) 2C8D94F0 xor 61707865 = 4DFDEC95.
В конце первого раунда, после инверсии, матрица будет выглядеть следующим образом:
Во втором раунде происходят те же изменения, с той же длинной смещения, опять начиная с под-диагональных слов и заканчивая диагональными словами. Такие действия продолжаются на протяжении заданного количества раундов.
После прохождения всех раундов, происходит сложение полученного массива с изначальным массивом для получения 64-байтной гаммы ключа.
Алгоритм шифрования ChaCha20
ChaCha20 – это алгоритм шифрования семейства Salsa20. Он использует те же принципы, но с изменениями, касающимися увеличения рассеивания в каждом раунде. Таким образом, минимальное количество защищенных раундов ChaCha меньше, чем таковое в Salsa20.
Основой алгоритма ChaCha является четверть-раунд, работающий с четырьмя 32-битными числами:
Операции ChaChar:
где a, b, c, d – 32-битные слова.
Начальная матрица ChaCha20 включает:
Четыре константы, расположенные в первой строке: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574.
Ключ, длинной 256 бит, причем каждые 4 байта расположены в обратном порядке.
Блоковый счетчик, длинной 32 бита.
Одноразовый код (nonce), длинной 96 бит, который не следует повторять для одного и того же ключа. Каждые 4 байта расположены в обратном порядке.
В ChaCha20 для формирования гаммы ключа используется система раундов, из которых десять вертикальных раундов и десять диагональных. Каждый раунд состоит из 4 четверть-раундов, порядок прохождения которых представлен на рисунке 19. После двадцатого раунда происходит сложение начальной и конечной матрицы для формирования поточного ключа.
Шифрование данных производится путем сложения по модулю 2 поточного ключа и открытого текста. Дешифрование происходит точно таким же образом, то есть шифртекст складывается по модулю 2 с поточным ключом.
Комментарии (6)
DGG
03.08.2023 14:58Некоторая проблема WireGuard и ChaCha20 в том, что алгоритм шифрования вроде как легче AES и в теории должен меньше нагружать слабые процессоры. Но под AES почти везде уже есть ускоряющие его наборы инструкций.
В результате какой-нибудь более "тяжёлый" OpenVPN с AES в настройках, батарейку телефона жрет меньше чем WireGuard
Number571
03.08.2023 14:58Нужно также ещё понимать, что ChaCha20 - это представитель поточных алгоритмом шифрования в которых генерация гаммы оторвана от шифруемого сообщения, и проблемой которых всегда является необходимость учитывать неповторяемость гаммы за счёт неповторяемости Nonce или ключа (как в RC4). В это же время, блочные алгоритмы более гибки в своей настройке за счёт режимов шифрования, хоть и в большинстве случаев менее производительны. И за счёт режимов, как пример, CBC, CFB, отпадает необходимость учитывать Nonce. Вполне достаточным остаётся использование случайного вектора инициализации. И даже если таковой повторится, то проблема сведётся к режиму ECB (с определённо установленным IV), а не к полной дешифровке нескольких сообщений.
domix32
03.08.2023 14:5832-битное смещение, представленное в виде, где a – 32-битное слов, а b – определенное количество бит, на которое происходит смещение.
Таки это смещение или поворот? Ибо обычно смещение обозначается
<<
а у вас везде оно<<<
datacompboy
"Мы берём два числа, складываем их. Таким образом, семейство алгоритмов сложения потенциально может претендовать на роль надежной и быстрой замены всех шифров мира."