PHP 3DES Шифрование

Это мой код

 $key = pack('H*', "11223344556677881122334455667788");
$plaintext = pack('H*', "0000000000000000");

$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $plaintext, MCRYPT_MODE_ECB);
echo bin2hex($ciphertext);

но результат, который я получил, 8ca64de9c1b123a7 отличался от этот сайт

6FB23EAD0534752B что я хочу

Может кто-нибудь объяснить, почему я получаю текст шифра, отличный от этого сайта?

2

Решение

У mcrypt есть — или, скорее, имел — неприятная привычка заполнять что-либо нулями, если размер не правильный. Хуже того, он также обрезает ключи до нужного размера, удаляя байты.

Как брезгливый оссифраж прокомментировал Кажется, что mcrypt поддерживает только три ключа DES. Это не так уж плохо, пока вы не заметите, что он с радостью примет 2-клавишный тройной ключ DES из 16 байтов, а затем дополнит его нулями, чтобы сделать его 3-клавишным тройным ключом DES. Конечно, он должен потерпеть неудачу, и более новые версии mcrypt должны это делать.

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

Лучше использовать другую криптографическую библиотеку, чтобы получить правильные результаты. mcrypt (лежащая в основе библиотека C) не поддерживалась в течение 8 лет или около того (и считала) и является чертовски дрянной.


Пример на Java (который также не полностью поддерживает 2-х ключевой DES):

    byte[] pt = new byte[16];
SecretKeyFactory fact = SecretKeyFactory.getInstance("DESede");
Cipher desEDE = Cipher.getInstance("DESede/ECB/NoPadding");

{
// usual 2-key triple DES:
byte[] keyData = Hex.decode("112233445566778811223344556677881122334455667788");
SecretKey generatedSecret = fact.generateSecret(new SecretKeySpec(keyData, "DESede"));
desEDE.init(Cipher.ENCRYPT_MODE, generatedSecret);
byte[] ct = desEDE.doFinal(pt);
System.out.println(Hex.toHexString(ct)); // result: 6FB23EAD0534752B
}

{
// "zero padded" 2-key triple DES:
byte[] keyData = Hex.decode("112233445566778811223344556677880000000000000000");
SecretKey generatedSecret = fact.generateSecret(new SecretKeySpec(keyData, "DESede"));
desEDE.init(Cipher.ENCRYPT_MODE, generatedSecret);
byte[] ct = desEDE.doFinal(pt);
System.out.println(Hex.toHexString(ct)); // result: 8ca64de9c1b123a7
}

Заметки:

  • Ваши ключи DES не полностью действительны, так как биты четности каждого байта установлены неправильно (однако они не используются в вычислениях DES);
  • лучше использовать AES и аутентифицированный режим шифрования, а не небезопасный режим ECB.
3

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

Других решений пока нет …

По вопросам рекламы [email protected]