Есть ли способ использовать коммутативное шифрование в php?

Я использовал encrypt а также decrypt функции из этого ответ реализовать передачу сообщений с использованием Трехпроходный протокол с шифром Blowfish.

И я попытался использовать коммутативное шифрование / дешифрование. То есть,

$tmp = encrypt($input, $key1);
$tmp = encrypt($tmp, $key2);
$tmp = decrypt($tmp, $key1);
$dec2 = decrypt($tmp, $key2);

Но это не работает. Я использовал один ключ вместо 2 разных ключей, и он работает (должен!).

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

Я делаю что-то неправильно? Это невозможно или есть другой способ?

Или есть ли способ сделать это на Java?

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

  1. Отправитель шифрует ключом 1 и отправляет

  2. Получатель шифрует ключом 2 и отправляет обратно

  3. Отправитель расшифровывает с помощью key1 и отправляет обратно

  4. Получатель расшифровывает ключом 2, чтобы получить исходное сообщение

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

0

Решение

Использование функции XOR, предоставленной пользователем в этой теме

Зашифровать / расшифровать с помощью XOR в PHP

    function xor_this($string,$key) {

// Our plaintext/ciphertext
$text =$string;

// Our output text
$outText = '';

// Iterate through each character
for($i=0;$i<strlen($text);)
{
for($j=0;($j<strlen($key) && $i<strlen($text));$j++,$i++)
{
$outText .= $text{$i} ^ $key{$j};
//echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
}
}
return $outText;
}

//The sender chooses a private encryption key s and a corresponding decryption key t. The sender encrypts the message m with the key s and sends the encrypted message E(s,m) to the receiver.
//The receiver chooses a private encryption key r and a corresponding decryption key q and super-encrypts the first message E(s,m) with the key r and sends the doubly encrypted message E(r,E(s,m)) back to the sender.
//The sender decrypts the second message with the key t. Because of the commutativity property described above D(t,E(r,E(s,m)))=E(r,m) which is the message encrypted with only the receiver's private key. The sender sends this to the receiver.

$senderkey=base64_encode('chicken');
$receiverkey=base64_encode('ardvark');

$itemwewanttoshare='hello darling';
echo'$itemwewanttoshare: '.$itemwewanttoshare.'<BR>';
$packet1=xor_this($itemwewanttoshare,$senderkey);
echo'$packet1: '.$packet1.'<BR>';

$packet2=xor_this($packet1,$receiverkey);
echo'$packet2: '.$packet2.'<BR>';

$packet3=xor_this($packet2,$senderkey);
echo'$packet3: '.$packet3.'<BR>';

$packet4=xor_this($packet3,$receiverkey);
echo'$packet4: '.$packet4.'<BR>';

Вы получаете это

$itemwewanttoshare: hello darling
$packet1: 1W6 TS>
$packet2: hNwRVtq|ing
$packet3: 1=&M"TS>
$packet4: hello darling

РЕДАКТИРОВАТЬ дополнение

Я base64’d ключ для простоты. Используйте ключ с большим количеством вариаций, и результаты будут более сложными.
использование mcrypt_create_iv(40) создать свои ключи, и вы получите что-то вроде этого

$senderkey='<²#H[Ô\´(µÑ/KÀ®"熺¥ç|Ëvr%O›eu$nºbe';
$receiverkey='Øh\5PÀKO[ù¬òZH‰•Ê¬h/¥nëk¾ðéíPÄ"Uü';

который изменит выход на

$itemwewanttoshare: hello darling
$packet1: T§ÞO'{§õ.®ÝF¥
$packet2: —?¶+¦6®½– þ
$packet3: «ý0Zpe¢ò"!<
$packet4: hello darling

Редактировать 2

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

1

Другие решения

Статья в википедии дает подсказку о том, что можно использовать:

Иногда функция шифрования и функция дешифрования совпадают.

Это относится к потоковым шифрам, таким как RC4, которые создают длинный поток псевдослучайных данных и просто XOR с данными. XOR коммутативен, и его легко реализовать на PHP:

$cipher = "arcfour";
$k1 = mcrypt_create_iv(256); // random
$k2 = mcrypt_create_iv(256); // random
$data = "some string";
$mode = "stream";

echo "key size: ".mcrypt_get_key_size($cipher, $mode)."\n"; // 256
echo "iv size: ".mcrypt_get_iv_size($cipher, $mode)."\n";   // 0

// Three-pass protocol property: D(d,E(k,E(e,m))) = E(k,m)
$c1 = mcrypt_encrypt($cipher, $k1, $data , $mode, "");
$c2 = mcrypt_encrypt($cipher, $k2, $data , $mode, "");
$c2 = mcrypt_encrypt($cipher, $k1, $c2 , $mode, "");
$c2 = mcrypt_decrypt($cipher, $k2, $c2 , $mode, "");

echo $c1 == $c2;

Блочные шифры в Режим CTR также можно использовать таким же образом. Это пример AES в режиме CTR:

$cipher = "rijndael-128";
$k1 = mcrypt_create_iv(16); // random
$k2 = mcrypt_create_iv(16); // random
$iv1 = mcrypt_create_iv(16); // random
$iv2 = mcrypt_create_iv(16); // random
$data = "some string";
$mode = "ctr";

echo "key size: ".mcrypt_get_key_size($cipher, $mode)."\n";
echo "iv size: ".mcrypt_get_iv_size($cipher, $mode)."\n";

$c1 = mcrypt_encrypt($cipher, $k1, $data , $mode, $iv1);
$c2 = mcrypt_encrypt($cipher, $k2, $data , $mode, $iv2);
$c2 = mcrypt_encrypt($cipher, $k1, $c2 , $mode, $iv1);
$c2 = mcrypt_decrypt($cipher, $k2, $c2 , $mode, $iv2);

echo $c1 == $c2;
0