2013-11-14 4 views
1

Я ищу способ генерации хэша SHA-512 из строки json в Ruby, независимо от положения элементов в нем и независимо от вложенности, массивов , вложенные массивы и т. д. Я просто хочу хэш сырые данные вместе со своими ключами.JSON генерирует уникальное значение хэша (SHA-512)

Я пробовал некоторые подходы с преобразованием JSON в хэш-рубин, глубоко сортировать их по их ключам, добавлять все в одну, длинную строку и хэш-код. Но я уверен, что мое решение не является самым эффективным, и что должен быть лучший способ сделать это.

EDIT

До сих пор я преобразовать JSON в хэш Ruby. Тогда я пытаюсь использовать эту функцию, чтобы получить каноническое представление:

def self.canonical_string_from_hash value, key=nil 
    str = "" 
    if value.is_a? Hash 
     value.keys.sort.each do |k| 
     str += canonical_string_from_hash(value[k], k) 
     end 
    elsif value.is_a? Array 
     str += key.to_s 
     value.each do |v| 
     str += canonical_string_from_hash(v) 
     end 
    else 
     str += key ? "#{key}#{value}" : value.to_s 
    end 
    return str 
    end 

Но я не уверен, если это хороший и эффективный способ сделать это.

Например, этот хэш

hash = { 
    id: 3, 
    zoo: "test", 
    global: [ 
    {ukulele: "ringding", blub: 3}, 
    {blub: nil, ukulele: "rangdang", guitar: "stringstring"} 
    ], 
    foo: { 
    ids: [3,4,5], 
    bar: "asdf" 
    } 
} 

конвертируется в эту строку:

barasdfids345globalblub3ukuleleringdingblubguitarstringstringukulelerangdangid3zootest 
+2

Пожалуйста, разместите решение, которое у вас есть. –

+0

Вам нужна каноническая форма для ваших данных, в которой вы можете утверждать, что две вещи являются «эквивалентными». Сглаживание структуры означает, что они действительно не эквивалентны (внутри Ruby) во многих отношениях, которые вам не нужны для вашего дайджеста, поэтому вам нужно четко понимать, что это означает для вас (т. Е. Когда два входа имеют одинаковые хэш, что вы хотите сказать о них?). На самом деле часть SHA здесь практически неактуальна, за исключением того, что нет ярлыка, где вы можете получить алгоритм дайджеста, чтобы сделать что-либо из этого для вас - он работает на неправильном уровне, чтобы помочь. –

+0

Сторона примечания: Хэш-значения SHA-512 * не уникальны. Их гораздо меньше, чем допустимых строк JSON. Однако их довольно много, и столкновения, вероятно, вас не затронут. –

ответ

1

Но я не уверен, если это хороший и эффективный способ сделать это.

В зависимости от того, что вы пытаетесь сделать. Ваши канонические/эквивалентные структуры должны представлять то, что для вас важно для сравнения. Удаление таких деталей, как структура объектов, имеет смысл, если вы рассматриваете два элемента с разной структурой, но одинаковые значения строк эквивалентны.

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

В этом случае весь ваш подход нуждается в переосмыслении. Причины, которые, вероятно, лучше всего обсудить на security.stackoverflow.com

Однако вкратце:

  • Используйте HMAC рутина (HMAC-SHA512), она предназначена для вашей цели. Вместо соли это использует секрет, который по сути является одним и тем же (на самом деле вам нужно также хранить свою соль в своей реализации, что необычно для чего-то, называемого солью), но сочетается с SHA в способ, который делает его устойчивым к нескольким формам атаки, возможно, против простой конкатенации, за которой следует SHA. Хуже всего то, что можно расширить данные и заставить их генерировать одну и ту же SHA при обработке, без необходимости знать соль.. Другими словами, злоумышленник может принять известный действительный запрос и использовать его для подгонки других запросов, которые пройдут проверку безопасности. Ваше предлагаемое решение выглядит уязвимым для этой формы атаки для меня.

  • Распаковка запроса и анализ деталей для получения «канонического» вида запроса не требуется, а также снижает безопасность вашего решения. Единственная причина для этого состоит в том, что вы по какой-то причине не можете обрабатывать запрос после его сериализации в JSON и вынуждены работать только с де-сериализованным запросом в одном или двух из двух систем. Если это чисто знание или вещь удобства, то исправить эту проблему, а не пытаться свернуть свой собственный протокол безопасности с помощью SHA-512.

  • Вы должны подписать запрос и проверить подпись на полностью сериализованной строке JSON. Если вам нужно де-сериализовать данные из атаки «человек в середине», вы потенциально уже можете столкнуться с некоторыми атаками через парсер. Вы должны работать, чтобы отклонить подозрительные запросы до того, как была сделана их обработка данных.

TL; DR - хотя и не является прямым ответом на ваш вопрос, правильное решение для вас, чтобы не писать этот код на всех. Вместо этого вам нужно поместить ваш защищенный код подписи ближе ко всем вашим услугам, которым нужно доверять друг другу.

Смежные вопросы