DTLS AES 256 CBC с SHA, как рассчитать окончательное зашифрованное рукопожатие - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь понять, как работает последнее сообщение Encrypted Handshake

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

https://www.cloudshark.org/captures/56acf0481a79

Я уверен, что DTLS 1.0 следует RFC 4347 из-за заголовка 0xFEFF.

Известны

Preshared Key: 123456789012345678901234567890aa
Server Random: d87eeeb79b8c5bb29a6e01236ca75a00d515ac18a060e7b4dd4aa85d66130b41
Client Random: df14cead6b8a82a7f0fa710ed4437fa747f5f20e160b6865a3486ca3abc1c427
Cipher Suite: TLS_PSK_WITH_AES_256_CBC_SHA

Я делаю следующий шаг:

Предварительный главный секрет

Секрет премастера формируется следующим образом: если длина PSK составляет N октетов, объедините uint16 со значением N, N нулевых октетов, второй uint16 со значением N и сам PSK. ( RFC 4279, раздел 2 )

  001000000000000000000000000000000000
  0010123456789012345678901234567890aa

Master_secret = PRF (pre_master_secret, «главный секрет», ClientHello.random + ServerHello.random) [0..47];

PRF определяется как объединение двух разных функций хеширования. Раздел 5 RFC 2246:

197c358a9de99d7c50120aea40af2095
c7c340719385f23f5355004c07d9f896
681942c494eb0d77992c3acf1bc92e4f 

key_block = PRF (SecurityParameters.master_secret, «расширение ключа», ServerHello.random + ClientHello.Random) в соответствии с RFC4346 Раздел 6.3

  • 20 байтов для клиентского MAC-ключа (SHA1)
  • 20 байт для MAC-ключа сервера (SHA1)
  • 32 байта для ключа шифрования клиента (AES256)
  • 32 байта для ключа шифрования сервера (AES256)
  • 16 байт для клиентского IV (AES использует 128-битные блоки)
  • 16 байт для сервера IV (AES использует 128-битные блоки)

В этом случае нам нужно сгенерировать 136 байт

4921654a071c95e2ddb8e3a8162258fa
acffdd8def0a0b7ce49f492a6f088af9
e539aae851232337c90564d6d4b01fb1
0b34466fe379e34b10b5738203453253
3fe0823297ca5c111b3d23dfb6145447
a638a84376f21a845de503b324f2beab
e145274f680519cc2ecc088e0bf6fb37
69b31c82df3ce706f6ac2cb45226234a
dbd564a2b43c79ee

Если вышеприведенное верно, то

Client Write Key: c90564d6d4b01fb10b34466fe379e34b
                  10b57382034532533fe0823297ca5c11
Client Write IV: 2ecc088e0bf6fb3769b31c82df3ce706

Поэтому, если я расшифрую запись зашифрованного рукопожатия клиента с ключом и IV выше, я получу

7fd6314cf559a60c14a44a2fd4ac5494
1400000c000200000000000ce93fd3d8
557a3eb9574d25943e01f797b982a5ed
35ce268520ef7475144441ea03030303

Как мне получить значение выше?

Я понимаю, что это необходимо хэшировать (объединение клиента Hello + Sever Hello + Sever Hello Done + Обмен ключами клиента)

010000390000000000000039feffdf14
cead6b8a82a7f0fa710ed4437fa747f5
f20e160b6865a3486ca3abc1c4270000
0006008d008c00ff0100000900230000
000f0001010200003600000000000000
36feffd87eeeb79b8c5bb29a6e01236c
a75a00d515ac18a060e7b4dd4aa85d66
130b4100008d00000eff010001000023
0000000f0001010e0000000001000000
00000010000011000100000000001100
0f436c69656e745f6964656e74697479

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 07 ноября 2018

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

14 00 00 0C 00 02 00 00 00 00 00 0C E9 3F D3 D8
55 7A 3E B9 57 4D 25 94 3E 01 F7 97 B9 82 A5 ED
35 CE 26 85 20 EF 74 75 14 44 41 EA 03 03 03 03

Начиная с конца, у нас есть следующие разделы:

PADDING (4 байта)

Последние четыре байта (03 03 03 03) заполнены, поэтому мы можем их пропустить.

MAC (20 байтов)

Следующие 20 байтов (3e 01 f7 97 b9 82 a5 ed 35 ce 26 85 20 ef 74 75 14 44 41 ea) - это HMAC-SHA1, рассчитанный особым образом: сначала нужно добавить эпоху + порядковый номер сообщения (в нашем случае 00 01 00 00 00 00 00 00), а затем добавить заголовок записи TLS (без эпохи и порядковый номер) с размером содержимого, установленным на фактический размер содержимого (в нашем случае 0x18):

00 01 00 00 00 00 00 00 16 FE FF 00 18 14 00 00
0C 00 02 00 00 00 00 00 0C E9 3F D3 D8 55 7A 3E
B9 57 4D 25 94

Давайте сохраним его в файл с именем handshake-client-finished-without-mac.bin и вызовем openssl:

$ openssl dgst -sha1 -hmac $(cat client-mac-key.bin) handshake-client-finished-without-mac.bin
HMAC-SHA1(handshake-client-finished-without-mac.bin)= 3e01f797b982a5ed35ce268520ef7475144441ea

MAC-ключ клиента (из сгенерированного вами блока ключей):

49 21 65 4A 07 1C 95 E2 DD B8 E3 A8 16 22 58 FA
AC FF DD 8D

Мы только что убедились, что MAC правильный. Давайте двигаться вперед с байтами сообщения.

ПРОВЕРКА ДАННЫХ (12 байт)

Следующие 12 байтов (E9 3F D3 D8 55 7A 3E B9 57 4D 25 94) - это данные проверки. Вы правильно извлекли байты из всех предыдущих сообщений. Теперь нам нужно вычислить MD5 и SHA1-хэш этих байтов:

$ openssl dgst -md5 to_hash.bin
MD5(to_hash.bin)= fcc3d19566dc07777834ebddf9dd5dc4

$ openssl dgst -sha1 to_hash.bin
SHA1(to_hash.bin)= 2b069b971ceb63e2f0e6d2687479a10b0aee6abd

Затем объедините их (md5 + sha1) и сохраните их в client-data-for-prf.bin. Наконец, мы вычисляем 12 байтов, используя функцию PRF (я использовал мою реализацию PRF из github ):

.\PRF.exe -l "client finished" -s .\master-secret.bin -d .\client-data-for-prf.bin -o
 client-prf-result.bin -n 12

client-prf-result.bin будет содержать байты, равные проверочным данным из зашифрованного сообщения.

ЖАТКА ДЛЯ РУЧКИ (12 байт)

Offset Field
00     Handshake Type: Finished (20)
01     Length: 12
04     Message Sequence: 2
06    Fragment Offset: 0
09    Fragment Length: 12

Примечание

Если вы когда-нибудь застряли во время игры с TLS, вы можете проверить журналы отладки Wireshark, которые многое раскрывают о том, что происходит на проводе. Щелкните правой кнопкой мыши по любому из кадров DTLS и откройте настройки протокола:

DTLS preferences

Затем установите предварительный общий ключ, который у вас уже есть, и выберите файл, в который вы хотите сохранить журналы:

Keys settings

Нажмите OK, и Wireshark расшифрует ваши данные TLS и предоставит вам много подробной информации в файле журнала.

...