2015-06-23 2 views
0

Я разрабатываю SSL-де-шифр в питоне, но у меня возникают некоторые проблемы на HMAC проверке:TLS MAC проверка сообщения

Я извлеченный все связанные с брелоком материал (клиент IV, MAC, ключом и сервер IV, MAC, ключ). Когда я получаю первое сообщение Application_Data (0x17), я могу его расшифровать, но не могу проверить целостность сообщения.

В RFC 2246 (https://www.ietf.org/rfc/rfc2246.txt), говорит:

МАС генерируется как:

HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + 
       TLSCompressed.version + TLSCompressed.length + 
       TLSCompressed.fragment)); 

, где "+" обозначает конкатенацию.

seq_num Номер последовательности для этой записи.

hash Алгоритм хеширования, заданный SecurityParameters.mac_algorithm.

Принимая это в качестве примера:

Chosen cipher_suite is TLS_RSA_WITH_AES_256_CBC_SHA256 

client_mac = "some random stuff" 
message_type = 0x17 
message_version = 0x0303 
encrypted_message_length = 1184 (IV|Message|MAC|Offset) 
decrypted_message_length = 1122 (removing IV, MAC and offset) 
message = "some message of length 1122" 
  • client_mac извлекается из keyring_material
  • message_type равно 0x17, так как тип сообщения Application_data, правильное значение должно быть 0x17
  • сообщений версия 0x0303, так как это TLS 1.2
  • длина сообщения 1122, удаление предшествующего IV, смещение и MAC verif ication, сообщение, получает окончательную длину 1122
  • seq_number является 1, как это первое сообщение

HMAC_SHA256 расчет, в питона, заключается в следующем:

import hashlib 
import hmac 
hmac.new(<client_mac>,label+message,hashlib.sha256).digest() 

Мой вопрос, как сделать Я рассчитываю ярлык? Как отмечает RFC, "+" обозначает конкатенацию, но конкатенация какие значения

  • HEX преобразуется в строку
    • "1" + "17" + "0303" + "462"
  • значения INT преобразуются в строки
    • "1" + "23" + "771" + "1122"

И другая вещь, говоря, TLSCompressed.version означает:

  • 0x0303
  • «1.2"
  • "12"
  • "TLS 1.2"

В этом Maillist (http://www.ietf.org/mail-archive/web/tls/current/msg14357.html) Я нашел предполагаемую уточнение значений MAC,

MAC(MAC_write_key, seq_num + 
     TLSCipherText.type + 
     TLSCipherText.version + 
     length of ENC(content + padding + padding_length) + 
     IV + 
     ENC(content + padding + padding_length)); 

, где длина кодированного как два байта обычным способом.

, но нет смысла м e, поскольку бесполезно перекодировать дешифрованные значения для проверки на вычисление MAC. А от последней строки «где длина кодируется как два байта в обычном порядке», делает это означает, что я должен использовать

struct.pack («! H», длина)

Затем удалите «\ x» и используйте это значение? или я должен кодировать это значение в HEX и затем конкатенировать его?

Я немного потерян, потому что RFC не ясно, как использовать значения.

Я пробовал несколько комбинаций (даже грубое форсирование), но никто из них не работал, я надеюсь, вы можете пролить свет.

ответ

0

Ну, после того, как diggin «немного мне удалось решить проблему.

RFC 5246, в разделе 6.2.3.1 (http://tools.ietf.org/html/rfc5246#section-6.2.3.1)

МАС генерируется как:

MAC(MAC_write_key, seq_num + 
         TLSCompressed.type + 
         TLSCompressed.version + 
         TLSCompressed.length + 
         TLSCompressed.fragment); 

, где "+" обозначает конкатенацию.

Но это не указывает размер данных, формат представления (hex, string ...).

Способ должен быть представлен каждое поле выглядит следующим образом:

  • seq_num:

    • Описание: INT счетчик, начиная с 0, который будет увеличиваться каждый кадр, полученный или отослано. Для сеанса TCP необходимо использовать два seq_numbers, один для сервера и другой для клиента, каждый раз увеличивая каждый из них, отправляя кадр.
    • Представление: Это значение должно быть представлено в виде Unsigned Long Long с 8 байт
    • Представление например: struct.pack("!Q",seq_num)
  • TLSCompressed.type

    • Описание: Это поле извлекается из Уровень записи TLS (зашифрованная полезная нагрузка).Например, если это кадр Application Data, мы должны использовать 0x17.
    • Представление: Это значение должно быть представлено как Подпись Char, с 2 байтами.
    • Представление Пример: struct.pack("!b",TLSCompressed.type)
  • TLSCompressed.version

    • Описание: Это поле также извлекается из слоя TLS Record (зашифрованный полезной нагрузки). Например, если кадр передается с использованием TLS 1.2, мы должны использовать его шестнадцатеричное представление 0x0303.
    • Представление: Это значение должно быть представлено как Unsigned Short, с 2 байтами.
    • Представление Пример: struct.pack("!H",TLSCompressed.version)
  • TLSCompressed.length

    • Описание: Это поле представляет собой фактическую длину расшифрованы полезную нагрузку.
    • Представление: Это значение должно быть представлено как Unsigned Short, с 2 байтами.
    • Представление Пример: struct.pack("!H",TLSCompressed.length)
  • TLSCompressed.fragment

    • Описание: Это поле фактическая ** расшифрованы полезной нагрузки.
    • Представление: Это значение должно быть представлено в виде строки

В качестве примера Python, хеширование HMAC будет выглядеть следующим образом для нашего предыдущего примера:

hmac_digest = hmac.new(mac_secret,'',digestmod=hashlib.sha256) 
hmac_digest.update(struct.pack('!QbHH',seq_num,TLSCompressed.type,TLSCompressed.version, len(decrypted))) 
hmac_digest.update(decrypted) 
hmac_digest.digest() 
Смежные вопросы