Создавать поистине глобально уникальный идентификатор для многих клиентов и серверов

Резюме

Действительно глобально уникальные идентификаторы во flash и/или javascript-клиентах. Могу ли я сделать это с помощью RNG, доступного в текущих браузерах /flash, или мне нужно построить составной идентификатор с случайной случайностью на стороне сервера?

Подробнее

Мне нужно генерировать глобально уникальные идентификаторы для объектов. У меня есть несколько "системных" систем на стороне сервера, написанных в java, которые должны иметь возможность обменивать идентификаторы; каждая из этих систем также имеет набор клиентов flex/javascript, которые фактически генерируют идентификаторы для новых объектов. Мне нужно гарантировать глобальную уникальность во множестве несвязанных систем; например, мне нужно иметь возможность объединять/синхронизировать базы данных двух независимых систем. Я должен гарантировать, что никогда не было столкновений между этими идентификаторами и что мне никогда не нужно менять идентификатор объекта после его создания. Мне нужно иметь возможность генерировать идентификаторы во Flash и javascript-клиентах, не связываясь с сервером для каждого идентификатора. Решение, которое полагается на какой-либо сервер, предоставило семенной или системный идентификатор, является прекрасным, если сервер не связывается слишком часто. Предпочтительно решение, которое работает полностью отключено. Аналогично, решение, которое не требует предварительной регистрации систем, предпочтительнее того, которое полагается на центральный орган (например, OUI по MAC-адресу).

Я знаю, что очевидным решением является "использование генератора UUID", например UIDUtil во flash. Эта функция специально отказывается от глобальной уникальности. В общем, я беспокоюсь о том, чтобы полагаться на PRNG, чтобы гарантировать глобальную уникальность.

Предлагаемые решения

Положитесь на защищенный генератор случайных чисел в клиенте.

Flash 11+ имеет flash.crypto.generateRandomBytes; Javascript имеет window.crypto, но он довольно новый и не поддерживается в IE. Существуют такие решения, как sjcl, которые используют мышь для добавления энтропии.

Я понимаю, что при идеальном RNG вероятность столкновения для случайного UID 2 122 является метеоритом крошечным, но я беспокоюсь, что на самом деле я не получаю эту степень случайности в javascript или флеш-клиентом. Я также обеспокоен тем, что типичный пример использования даже криптографического RNG отличается от моего: для сеансовых ключей и т.д. Конфликты приемлемы, если они непредсказуемы злоумышленником. В моем случае столкновения совершенно неприемлемы. Должен ли я действительно полагаться на исходный вывод безопасного RNG для уникального идентификатора?

Сгенерировать составной идентификатор, который включает идентификаторы системы, сессии и объекта.

Очевидной реализацией будет создание системного UUID во время установки сервера, сохранение идентификатора сеанса для каждого клиента (например, в базе данных), а затем отправка идентификатора системы и сеанса на клиент, который будет хранить каждый -сегментный счетчик. Uid будет тройной: идентификатор системы, идентификатор сеанса, клиентский счетчик.

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

Ключевые вопросы

  • Случайная или композитная на основе?
  • Включить идентификатор системы?
  • Если системный идентификатор: сгенерировать случайный идентификатор системы или использовать центральный реестр?
  • Включить метку времени или какой-то другой nonce?
  • К хешу или не к хешу?

Ответ 1

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

Другим простым подходом является создание набора уникальных идентификаторов (скажем, 2k за раз) на сервере и отправка их в пакет для каждого клиента. Когда у клиента заканчиваются идентификаторы, он больше связывается с сервером.

Идентификаторы клиентов должны храниться в центральном репозитории, доступном для всех серверов.

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

Чтобы ответить на ваши вопросы, вам нужно определить преимущество, которое добавила бы сложность системного идентификатора, nonce или hash.

Идентификатор системы: Системный идентификатор обычно используется для уникальной идентификации системы внутри домена. Поэтому, если вам все равно, кто пользователь, или сколько сеансов открыто, но только хотите убедиться, что вы знаете, кто это устройство, затем используйте системный идентификатор. Это обычно менее полезно в пользовательской среде, такой как JavaScript или Flash, где пользователь или сеанс могут быть релевантными.

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

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

Хэш: В то время как хэши часто используются (ab) для создания уникальных ключей, их реальная цель - сопоставить большой (возможно, бесконечный) домен с меньшим, более управляемым. Например, MD5 обычно используется для генерации уникального идентификатора из временной метки, случайного числа и/или данных nonce. Фактически происходит то, что функция MD5 отображает бесконечный диапазон данных в пространство возможностей 2 ^ 128. Хотя это массовое пространство, оно не бесконечно, поэтому логика говорит вам, что будет (хотя бы в теории) тот же хеш, присвоенный двум различным фрагментам. С другой стороны, идеальное хеширование пытается назначить уникальный идентификатор каждой части данных, однако это совершенно не нужно, если вы просто назначаете уникальный идентификатор каждому фрагменту клиента, чтобы начать с него.

Ответ 2

Что-то быстрое и грязное, а также может не сработать для вашего случая использования -

Использование Java UUID и связывание с чем-то вроде, скажем clientName. Это должно решить проблему multiple client and multiple server.

Обоснование этого заключается в том, что возможность получения двух вызовов в одну и ту же наносекунду является низкой, см. ссылки, приведенные ниже. Теперь, связывая имя clientName с UUID, вы обеспечиваете уникальные идентификаторы для клиентов, и это должно оставить только обработку варианта использования того же клиента, который дважды звонит в пределах той же наносекунды.

Вы можете написать java-модуль для генерации идентификаторов, а затем заставить Flash поговорить с этим модулем. Для справки вы можете обратиться к -
Уникально ли генерация идентификаторов с использованием UUID действительно? Получение java и flash для общения друг с другом

Ответ 3

Средняя точка основывается на ответе @ping:

  • Использовать имя клиента, время с высоким разрешением и, возможно, другое псевдослучайное семя
  • Хешируйте данные для создания UID (или просто перейдите непосредственно к использованию UUID)
  • Запишите полученный результат на центральный сервер для входа в базу данных
  • Рассматривайте любое столкновение как заметную ошибку, а не как ситуацию, которая заслуживает специального кода.

С UUID или достаточно длинным хэшем, шансы на дублирование или ноль. Итак, либо:

A) Вы не получите дубликатов для жизни приложения, жизнь хорошая.  B) В течение нескольких десятилетий вы увидите дубликат, или, может быть, два (причудливый!). Вступайте в действие вручную, чтобы справиться с этими случаями; если вы используете серверы с вашим клиентом, вы можете себе это позволить.  C) Если вы получите третье столкновение, то в коде есть что-то принципиально неправильное, и это можно исследовать и принять меры, чтобы избежать повторения.

Таким образом, идентификатор создается на клиенте, контакты с сервером являются однонаправленными и оперативно некритичными, семена не обязательно должны быть случайными, хеширование скрывает происхождение идентификатора и поэтому позволяет избежать создания столкновений, и вы можете быть уверены, что никаких столкновений не было. (Если вы проверите этот код обнаружения столкновения!) Даже UUID могут быть достаточными в этом сценарии.

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

Ответ 4

Мои два цента. Каждый сервер блокирует таблицу БД и получает от нее идентификатор и увеличивает его. это будет уникальный идентификатор сервера.

Каждое соединение с клиентом будет получать этот идентификатор вместе с уникальным идентификатором, выданным сервером. Этот уникальный ключ должен быть уникальным для этого сервера, но другой сервер может выдавать один и тот же идентификатор другому клиенту.

Наконец, каждый клиент будет генерировать уникальный идентификатор для каждого запроса.

Соединение всех трех будет гарантировать истинный уникальный глобальный идентификатор по всей системе, последний идентификатор будет выглядеть примерно так:

[server id][client id][request id]

Ответ 5

Хотя это добавит лишние накладные расходы, уникальный идентификатор TRULY может быть создан только на одном компьютере. Добавьте еще, и у вас есть просто вероятность.

Мое предложение состоит в том, что если вы действительно отчаянно нуждаетесь в уникальном глобальном id, запросите заданный сервер для uid.

Однако это может быть конструктивным недостатком в вашей логике, потому что для большинства приложений, требующих уникальный идентификатор, необходимо, чтобы он взаимодействовал с сервером, и в этом случае SERVER должен сначала обслуживать uid