Как зашифровать одно сообщение для нескольких получателей?

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

например, данные шифруются паролем пользователя и паролем его компании, а затем он или его компания может расшифровать данные. Ни один из них не знает другого пароля. Хранится только одна копия зашифрованных данных.

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

Update: я также хотел бы найти решение, которое не связано с хранением ключей вообще.

5 ответов


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

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


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


Если я правильно вас понял, у вас есть некоторые данные, которые вы готовы зашифровать и распространить ключ шифрования, разделенный на n "частей ключа".(В вашем случае 2 штуки)

для этого вы можете использовать разделение на основе XOR, вот как это работает: Вы предоставляете необходимое количество штук-n, а секретный ключ-K. чтобы сгенерировать n штук вашего ключа, вам нужно создать (n – 1) случайных чисел: R1, R2, R3, . . . , Rn-1. Для этого вы можете использовать генератор чисел SecureRandom, что предотвратит дубликаты.Затем вы используете функцию XOR на этих частях Rn-1 и ваш ключ-K:
РН = Р1 ⊕ Р2 ⊕ R3 И ⊕ . . . ⊕ Rn - 1 ⊕ K

Теперь у вас есть n штук: R1, R2, R3, ..., Rn-1, Rn, и вы можете уничтожить K. эти части могут быть распространены в вашем коде или отправлены пользователям.

для того чтобы собрать ключ, Мы используем деятельность XOR на наших частях Rn:
К = Р1 ⊕ Р2 ⊕ R3 И ⊕ . . . ⊕ Rn-1 ⊕ Rn

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

для получения дополнительной информации и кода Вы можете взглянуть на утилиту Android, которую я написал для этой цели:
Проект GitHub:https://github.com/aivarsda/Secret-Key-Split-Util

также вы можете попробовать демо-приложение Secret Key Splitter, которое использует эту утилиту :
в googleplay: https://play.google.com/store/apps/details?id=com.aivarsda.keysplitter


Я думаю, что я подумал о решении, которое будет работать:

D = data to encrypt
h1 = hash(userpassword)
h2 = hash(companyPassword)
k = h1 concat h2

E = function to encrypt
//C is the encrypted data
C = E_h1(h2) concat E_h2(h1) concat E_k(D)

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

возможно, есть лучшее решение, чем это?


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

один из способов сделать это-создать полином порядка t-1, установить секрет в качестве первого коэффициента и выбрать остальные коэффициенты случайным образом. Затем, Н случайные точки На этой кривой выбираются и становятся акциями.