LINUX.ORG.RU

Надежное шифрование небольших непоследовательных кусков данных от 1 до 2¹⁶ байт

 , ,


0

2

Как безопаснее всего сделать шифрование кусков данных размером от 1 до 2¹⁶ байт? Нужно иметь возможность расшифровать любой без обработки соседних, так что шифровать все подряд CBC не получится. ECB ненадежный.

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

Я думал над тем, чтобы взять AES-256-CBC для каждого отдельного пакета и добавлять рандомный шум по 16 байт вначале и в конце перед шифрованием, но это будет давать оверхед по 32 байта на пакет (не считая padding)

+---------------------+
| random data 16 byte |
+---------------------+
|      user data      |
+---------------------+
| random data 16 byte |
+---------------------+

Есть ещё идеи? Данные предназначены для длительного хранения.

Я понимаю, что велосипеды - это плохо. Как делают серьёзные ребята?

Читал ещё про CTR, но я не уверен, смогу ли сделать уникальный счётчик, т.е., впишется ли это в мою модель данных.

★★★★★

Последнее исправление: Chaser_Andrey (всего исправлений: 2)

но я не уверен, смогу ли сделать уникальный счётчик

Как-то совсем непонятно, что за проблемы у тебя со счётчиком.

prischeyadro ★★★☆☆
()
Ответ на: комментарий от prischeyadro

что за проблемы у тебя со счётчиком

потому что — куски не последовательные!

(но правда я не очень понимаю как они могут быть непоследовательными :) .. ведь даже непоследовательность — можно пронумеровать как последовательность)

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

[cast prischeyadro]

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

Сервер предоставляет возможность синхронизации зашифрованных данных.

Единственное, что я могу придумать в качестве счётчика - это какой-то хэш ещё не зашифрованных данных SHA1 (SHA256?) с солью. Соль можно генерировать из пароля, но не сообщать серверу, так как пароль одинаковый, то и соль на всех девайсах будет совпадать.

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

Так вот, тут последовательно пронумеровать нельзя :( А можно ли использовать длинные числа (16 байт или больше) в качестве счётчика в прикладных реализациях AES-CTR я ещё не узнавал.

Chaser_Andrey ★★★★★
() автор топика
Последнее исправление: Chaser_Andrey (всего исправлений: 1)
Ответ на: комментарий от Chaser_Andrey

то есть суть в том что сервер сам этого ключа НЕ знает?

он принимает куски данных и хранит их (при желании выдаёт, клиенту) — но сам не знает что именно он хранит?

верно понял? :-)

[если это НЕ так — то сервер мог бы заняться сортировкой и перешифрованием того что получил ранее от источников.. а связывался бы с каждым источниками данных — через индивидуальные ключи (а не через общий ключ) для каждого из источников]

user_id_68054 ★★★★★
()
Ответ на: комментарий от Chaser_Andrey

где-то что-то такое я уже читал на ЛОР.. кто-то отписывался что мол хочет организовать систему бэкапов из разных серверов, но так чтобы «левая рука не знала бы ни чего о правой руке» (орбазно выражаясь :))

user_id_68054 ★★★★★
()
Ответ на: комментарий от Chaser_Andrey

Данные генерируются на нескольких устройствах независимо

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

наиболее надежным я на свой профанский взгляд назвал бы свой IV на каждом устройстве и независимые счетчики.

maloi ★★★★★
()
Ответ на: комментарий от maloi

IV разный на устройствах?
если да, то и счетчик нужно делать независимым на каждом устройстве.

а в CTR — IV это и есть часть счётчика... :)

то есть сам счётчик состоит из IV+i , где i=i+1 на каждом следующем блоке

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 1)
Ответ на: комментарий от user_id_68054

а в CTR — IV это и есть часть счётчика... :)

судя по вики - нет, IV - это IV, а счетчик - это счетчик. там где в ECB передают IV в CTR передают IV+счетчик.

The IV/nonce and the counter can be combined together using any lossless operation (concatenation, addition, or XOR) to produce the actual unique counter block for encryption.

maloi ★★★★★
()
Ответ на: комментарий от user_id_68054

может ты хотел сказать, что счетчик является частью IV?
тогда ты в каком-то смысле прав (если считать CTR модификацией ECB с вычисляемым для каждого блока IV)

maloi ★★★★★
()
Ответ на: комментарий от maloi

может ты хотел сказать, что счетчик является частью IV?

на каждую порцию данных (порция данных — это несколько блоков) — используется уникальный IV..

а на каждый блок — используется уникальное значение счётчика...

а вот теперь подумай что является частью чего :-)

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

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

maloi ★★★★★
()

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

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

Если тебе требуется как шифрование, так и расшифрование произвольного блока, то вариантов у тебя немного.

Oxana
()
Ответ на: комментарий от Chaser_Andrey

Ну у тебя стандартная задача же. К каждому блоку прикладываем известный уникальный псевдорандомный IV, тогда блок можно расшифровать независимо от остальных блоков, что с CBC, что с CTR. Единственное, в чём отличие от стандартной задачи — сделать так, чтобы независимо генерируемые на несвязанных серверах IV не совпали. Можно для генерации IV использовать независимые счётчики, но каждый со своим диапазоном+какая-нибудь общая для всех рандомная соль, и шифровать их дополнительным общим ключом.

prischeyadro ★★★☆☆
()

Возможно я не совсем понял проблему, но могу вам предложить повысить энтропию данных перед шифрованием, таким образом что даже один и тотже блок данных будет иметь обсалютно отличную сигнатуру. Для этого можно данные в каждом блоке шифровать дважды. Например нужно передать блок из 16 байт, в начале мы генерируем случайный ключ (пусть будет 4 байта) и криптуем наши 16 байт этим ключем (например делаем простой XOR со здвигом, для больших блоков можно применить чтото по серьезней вроде 3DES/AES), далее формируем промежуточный блок из 20 байт (ключ + зашифрованые данные) - после все шифруем с помощью секретного ключа и отправляем в сеть.

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

zaz ★★★★
()

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

zaz ★★★★
()
Ответ на: комментарий от user_id_68054

то есть суть в том что сервер сам этого ключа НЕ знает?

он принимает куски данных и хранит их (при желании выдаёт, клиенту) — но сам не знает что именно он хранит?

Именно. Что-то похожее на Firefox Sync (с точки зрения пользователя), только у меня суммарный объем данных может достигать сотен мегабайт.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от xtraeft

А устройства случайно не поддерживают AES аппаратно?

Некоторые - да, некоторые нет. Только я не пойму, как аппаратная поддержка AES может мне помочь.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от prischeyadro

К каждому блоку прикладываем известный уникальный псевдорандомный IV

Может ли этим служить 16-байтное число?

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

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

xtraeft ★★☆☆
()
Ответ на: комментарий от xtraeft

Клиенты - это десктопы (Linux/Windows/BSD/MacOS), мобильные платформы (пока только Android, остальные в планах). Речь не идет об узкоспециализированных железках.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от prischeyadro

Или даже лучше 20[32]-байтное. Тогда можно в качестве уникального IV использовать хэш данных, который гарантирует приемлемую защиту от коллизий. Я что-то забыл, что SHA1 - 20 байт занимает. А меньший размер хэша мне кажется небезопасным.

Допустим, data - мой кусок данных. passwd - пароль, известный только клиентам, но не серверу.

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

IV = hash(hash(data) + salt)

Так можно?

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

Или даже лучше 20[32]-байтное

Размер IV у тебя зависит от размера элементов блока. Ты его вряд ли сможешь свободно менять.

Тогда можно в качестве уникального IV использовать хэш данных, который гарантирует приемлемую защиту от коллизий.

И получить одинаковые IV и, в конечном счёте, полностью одинаковые шифротексты для двух одинаковых исходных блоков (например, кусков данных, забитых нулями). IV придумывалось ровно для того, чтобы этого не было.

prischeyadro ★★★☆☆
()
Ответ на: комментарий от prischeyadro

и, в конечном счёте, полностью одинаковые шифротексты для двух одинаковых исходных блоков

Верно... спасибо.

Chaser_Andrey ★★★★★
() автор топика
27 апреля 2015 г.

А метод одноразового шифроблокнота не пойдёт? С ключом размером с входные данные

Harald ★★★★★
()
Последнее исправление: Harald (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.