Это легко сделать, переведя любой алгоритм блочного шифрования в режим CTR . Режим CTR с одной клавишей выглядит так:
ciphertext = plaintext XOR cipher(key, counter)
Где счетчик инициализируется вашим IV и увеличивается для каждого блока. Расшифровка точно такая же операция. Таким образом, если вы дважды шифруете CTR двумя ключами, вы получите:
ciphertext = plaintext XOR cipher(key0, counter) XOR cipher(key1, counter)
И поскольку XOR коммутативен, вы можете изменить его в любом порядке.
У этого приятного свойства нет необходимости располагать все ключи в одном месте. Обратите внимание: Алиса, Боб и Чарли участвуют в протоколе, в котором Чарли будет дважды шифровать данные как для Алисы, так и для Боба (этот протокол будет предполагать, что вся двухточечная связь защищена через обычные SSL-подобные каналы):
- Алиса и Боб выполняют аутентифицированный обмен Диффи-Хелманна для создания IV. Этот IV затем отправляется Чарли.
- Алиса вычисляет дайджест (key0, IV + ctr) для ctr = 0 ... number-of-ciphertext-blocks и отправляет результат KS_A Чарли
- Боб вычисляет дайджест (key1, IV + ctr) для ctr = 0 ... number-of-ciphertext-blocks и отправляет результат KS_B Чарли
- Чарли вычисляет открытый текст KS_A XOR KS_B XOR и отправляет полученный зашифрованный текст Алисе и Бобу.
- Алиса и Боб каждый подписывают кортеж (IV, хэш (зашифрованный текст), описание зашифрованных данных). Это прикреплено к зашифрованному тексту.
Позже, чтобы расшифровать:
- Чарли (выполняет расшифровку) отправляет подписанные (IV, хэш (шифротекст)) кортежи каждому из Алисы и Боба, а также зашифрованный текст.
- Алиса проверяет свой подписанный кортеж, вычисляет KS_A и отправляет зашифрованный текст XOR KS_A = D_A Чарли
- Боб проверяет свой подписанный кортеж, вычисляет KS_B и отправляет зашифрованный текст XOR KS_B = D_B Чарли
- Чарли вычисляет KS = D_A XOR D_B = KS_A XOR KS_B
- Чарли вычисляет открытый текст = зашифрованный текст XOR KS
Цель подписанного здесь кортежа и обмена DH состоит в том, чтобы гарантировать, что Алису и Боба не удастся обмануть в неправильном потоке, отправив им другой IV. Это может не относиться к вашему сценарию использования. Кроме того, роль Чарли может сыграть Алиса или Боб в реальной реализации.
Если вас беспокоит потенциальная угроза безопасности режима CTR, еще одним вариантом будет использование шифрования в режиме CTR для ключа сеанса, который, в свою очередь, используется для шифрования в более обычном режиме, таком как * 1043. * CBC . То есть:
sessionkey = RANDOM
IV_0 = RANDOM
IV_1 = RANDOM
enc_sessionkey = sessionkey XOR cipher(key0, IV_0) XOR cipher(key1, IV_0)
ciphertext = enc_sessionkey + IV_0 + IV_1 + cipherCBC(IV_1, sessionkey, plaintext)
Хотя некоторые другие авторы прокомментировали совместное использование секрета, это излишне, если вам не нужно свойство, что для расшифровки требуется только подмножество ключей - то есть с секретным обменом вы можете зашифровать с тремя ключами, но требовать только любые два для расшифровки. Если вы хотите требовать все ключи, секретные схемы обмена на самом деле не нужны.