Обеспечение полноты и достоверности данных на стороннем хранилище


Я имею дело с ненадежным внешним хранилищем и должен убедиться, что поставщик хранилища не удерживает никакие записи в запросе.

Пример:

У меня есть две доверенные сущности TA и TB, эти сущности должны иметь возможность изменять данные, хранящиеся в облаке/ненадежном хранилище, но никто другой. Поэтому мое решение я оснащаю TA и TB открытыми ключами, и у меня есть структура данных, которую можно сравнить с таблицей с версиями, скажем

 Ver | Data | Signature       | Signee
  4  |  ... | (AAAAAAAAA)_TA  | TA
  3  |  ... | (ZZZZZZZZZ)_TB  | TB
  2  |  ... | (YYYYYYYYY)_TA  | TA
  1  |  ... | (XXXXXXXXX)_TA  | TA

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

Однако я также хотел бы проверить полноту записи. Скажем, TA загружает версию 4, но TB знает только обо всех записях до версии 3. Теперь поставщик хранилища может полностью отказаться от версии 4, Когда TB запрашивает ее.

Поскольку нет прямого бокового канала между TA и TB, нет никакого способа обменять текущая версия. Есть ли способ обойти это?

Я подумывал о том, чтобы периодически вставлять фиктивные записи, чтобы по крайней мере иметь некоторую уверенность во времени. Однако этот подход не обладает масштабируемостью и приведет к большим затратам на хранение и подписание. Что такое фактическое системное свойство, которое я ищу (трудно найти исследование для чего-то, что вы не знаете названия)?

2 10

2 ответа:

Эта проблема не вполне разрешима без фиктивных записей:

Назовем состояние, когда текущая версия является версией 3, "состоянием 3", а состояние, когда текущая версия является версией 4,"состоянием 4". Независимо от того, как вы подписываете эти состояния - до тех пор, пока злоумышленник говорит вам "состояние 3 является текущим" (показывая вам всю базу данных, как это было во время состояния 3), Вы не можете знать, является ли это правдой или состояние 4 существует в то же время.

Таким образом, вам придется периодически подписывайте обновления "без изменений". Вы не сможете избежать накладных расходов на подписание, но вам не нужно хранить все это. Вы делаете отдельную таблицу "lastupdate":

 Signer | Last | Timestamp | Signature
  TA    |  4   | 2013-1... | (TA;4;2013-1...)_TA
  TB    |  3   | 2013-1... | (TB;3;2013-1...)_TB

Означает " подписавший та подтверждает это по состоянию на 2013-1..., последняя версия, присланная мной, была 4". Если поставщик хранилища не может показать вам текущее подтверждение от всех подписавших, что они не выпустили более новую версию, вы должны предположить, что он что-то скрывает (или что-то сломалось-в любом случае, данные не являются актуальными). Любое новое подписанное заявление заменяет более старые из этого подписывающего, потому что они теперь неуместны.

Теперь, если у вас есть не только одна версионная "вещь", но и большое их количество, вам не обязательно иметь один такой фиктивный журнал на "вещь". Например, вы можете вычислить хэш (или хэш-дерево) по всем наиболее текущим строкам вашим подписчиком (например, "Thing A, Version 3. Вещь Б, Версия 7. Вещь С, Версия 2."), а затем просто положить гашиш или корень из хэш-дерево в таблице lastupdate.

Если Вы действительно хотите избежать дополнительных подписей, и некоторые вещи постоянно обновляются, вы можете включить хэш и метку времени в подписи подписываемых вами записей версий - самая последняя подписанная запись будет достаточным доказательством свежести, и если она слишком стара, вы все еще можете использовать таблицу "lastupdate". Это не стоит сложностей, ИМХО.

Если проблема заключалась в целостности записи, я бы рекомендовал использовать MAC (код аутентификации сообщения). В этом случае следует использовать шифрование с симметричным ключом, а оно гораздо эффективнее, чем криптографические подписи (асимметричные).

Я думал о двух направлениях:

  1. Вы можете свести свою проблему к целостности записи. Если у вас есть определенные важные данные, которые вы хотите проверить, вы можете просто создать определенную таблицу в хранилище, которая сохраняет, когда каждый из доверенные сущности обновили каждую из ваших важных переменных. Важными данными могут быть: количество записей (всего, новых, по какой-то категории), последняя версия и т. д. Когда кто - то вносит изменения, влияющие на важные данные, он обновляет соответствующую запись в пространственной таблице и подписывает запись-и запись содержит также дату последнего обновления. Теперь, чтобы предотвратить возврат старых записей или подобных вещей ненадежным хранилищем, каждая из доверенных сторон должна обновить записи по крайней мере один раз в некоторый период времени (например - один день)- записи могут не изменяться (только дата в записи), а знак будет меняться (теперь знак находится на более поздней дате). Когда сущность считывает информацию, она может проверить, что данные являются подлинными и были истинными в течение (в Примере) не более одного дня до этого. Если дата возвращенной записи старше одного дня, то она не должна учитываться. Вы можете изменить частоту периодических обновлений в соответствии с вашими потребностями. Для этого вариант вы можете использовать MAC вместо подписей, а также (для повышения эффективности).

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

Последнее, что вы написали:

Поскольку нет прямого бокового канала между TA и TB, нет никакого способа для обмена текущей версией. Есть ли способ, чтобы обойти это?

Я полагаю, вы имели в виду канал связи. Боковой канал - это что-то другое. Если бы это был я, я бы просто создал такой канал связи, чтобы решить проблему. И кстати, аналогично первому варианту, который я описываю, можно создать такой канал:

Создайте таблицу сообщений от различных сущностей, где они объявляют о важных изменениях, которые они сделали, и подписывают их с датой изменения:

Сущность / Изменения / Дата | Подпись (или MAC)

Как и в первом варианте, каждая сущность должна добавлять такое сообщение один раз в некоторый заранее определенный период времени - и у вас есть надежный канал связи между сущностями.