Функция PHP XOR реализует & quot; Длина не соответствует & quot;

Я написал простую функцию XOR в PHP. Он отлично работает, но всегда выдает исключение «Длина не соответствует», когда я реализую его в классе.

Функция XOR:

private static function strxor($dataA, $dataB) {
if (($dataLen = strlen($dataA)) != strlen($dataB)) {
throw new Exception("Length Not Match in strxor");
}
$result = '';
for ($i = 0; $i < $dataLen; $i++) {
$result .= $dataA[$i] ^ $dataB[$i];
}
return $result;
}

Я даже попробовал другую версию, которая скопирована с Зашифровать / расшифровать с помощью XOR в PHP, с добавленной проверкой длины и измененным именем переменной.

private static function xor_this($dataA, $dataB) {
if (($dataLen = strlen($dataA)) !== strlen($dataB)) {
die("Length Not Match in xor_this");
}
$result = '';
for($i=0;$i<$dataLen;) {
for($j=0;($j<$dataLen && $i<$dataLen);$j++,$i++) {
$result .= $dataA{$i} ^ $dataB{$j};
}
}
return $result;
}

Класс, который я собираюсь реализовать:

public static function encrypt($key, $data) {
$iv = parent::genSafeRandomBytes(16);
$nonce = parent::genSafeRandomBytes(16);
$firstBlock = self::xor_this($nonce, $iv);
$salt = parent::genSafeRandomBytes(16);
$hmac = parent::signText($data, $key);
$subkey = parent::genSubKey($key, $salt);
$data = self::pkcs7pad($data);
$data = str_split($data, 16);
$tmp_r = openssl_encrypt($firstBlock, self::CIPHER, $subkey, OPENSSL_RAW_DATA);
$result = '';
for ($i = 0; $i < count($data); $i++) {
$tmp_n = parent::ivAdd($nonce, $i+1);
$tmp_n = self::xor_this($tmp_n, $tmp_r);
$tmp_x = openssl_encrypt($tmp_n, self::CIPHER, $subkey, OPENSSL_RAW_DATA);
$result .= $tmp_r = self::xor_this($tmp_x, $data[$i]);
}
return Base62::encode($iv.$nonce.$salt.$hmac.$result);
}

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

Полный источник: https://gist.github.com/hartmantam/39857700831591775b1c (не работает)

2

Решение

Добавив функцию отладки, я, наконец, обнаружил, что проблема не в функции XOR, а в openssl_encrypt функция. Поскольку размер блока AES равен 16, и я правильно его ввел, функция добавит еще один блок в открытый текст, что приведет к двойному выводу, поэтому возникает эта ошибка.

Решение довольно простое: Изменить OPENSSL_RAW_DATA в OPENSSL_ZERO_PADDING, а затем функция не будет выполнять заполнение. Хотя эта проблема решена, теперь от нас требуется заполнить сообщение вручную, и он выведет Base64 закодированная строка.

Изменить все openssl_encrypt как показано ниже, и замените первую переменную, если необходимо.

openssl_encrypt($firstBlock, self::CIPHER, $subkey, OPENSSL_ZERO_PADDING);

Все что я хочу сказать: странный дизайн

0

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

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

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