Как получать всегда те же результаты в encriptar цепь?

У меня есть эта функция, которая подает для encriptar цепи:

public function encriptar($string) {
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), 
                            MCRYPT_DEV_URANDOM);
    $encrypted = base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                                                    hash('sha256', getKey(), true), 
                                                    $string, MCRYPT_MODE_CBC, $iv));    
    return $encrypted;
}

Проблема состоит в том, что всегда меня возвращает отличная стоимость даже добавляя ту же цепь. Пример:

Я вхожу: StackOverflow

Результат: InT3g0AUXXTrmCAxrlht5ZVe8GBmlgGDMotXuVu11hI =

Если я вновь выполняю рукописный шрифт:

Я вхожу: StackOverflow

Результат: ImhWn5vPA/A2NY2wpUwg7VLWAiGBls80Z84fGU303Ws =

Если я вновь выполняю рукописный шрифт:

Я вхожу: StackOverflow

Результат: FqvxSsblSwz5riaDnnq7h20PzZTPdk/K+dikLHbLHTY =

Как я могу делать для того, чтобы это всегда была та же стоимость?

15
задан 29.12.2016, 19:00
1 ответ

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

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

Я оставляю тебе функцию, извлеченный отсюда:

Эти функции не являются безопасными ни подходящими, чтобы сохранять пароли!

function encrypt($pure_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
    return $encrypted_string;
}

function decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}


define("LLAVE_SECRETA", "!@#$%^&*");

$string = 'Hola Mari Carmen';

$encrypt = encrypt($string, LLAVE_SECRETA);

echo $encrypt; // ��0we��[�;���v

$decrypt = decrypt($encrypt, LLAVE_SECRETA);

echo $decrypt; // Hola Mari Carmen

Видеть Demo

2
ответ дан 24.11.2019, 12:38

Он должен бы быть используя openssl_encrypt() и openssl_decrypt()

mcrypt это не хорошая идея, так как он не стал отвечающим совремнным требованиям с 2007.

Даже есть RFC, чтобы удалять mcrypt PHP

Шрифт SO:

Пример: openssl_encrypt() и openssl_decrypt()

<?php
 /**
 * https://stackoverflow.com/questions/9262109/php-simplest-two-way-encryption/30189841#30189841      
 */
    class UnsafeCrypto
    {
        const METHOD = 'aes-256-ctr';

        /**
         * Encrypts (pero no autentificar) un mensaje.
         * 
         * @param cadena $mensaje - mensaje texto plano
         * @param cadena $clave - clave encriptado (raw binary expected) (binario sin procesar)
         * @param booleano $codificar - establecido en TRUE para devolver un base64-encoded 
         * @return cadena (raw binary)
         */
        public static function encrypt($mensaje, $clave, $codificar = false)
        {
            $tamano = openssl_cipher_iv_length(self::METHOD);
            $mientras = openssl_random_pseudo_bytes($tamano);

            $texto_cifrado = openssl_encrypt(
                $mensaje,
                self::METHOD,
                $clave,
                OPENSSL_RAW_DATA,
                $mientras
            );

            // Ahora empaquemos el IV y el texto cifrado
            // Nativamente, sólo podemos concatenar
            if ($codificar) {
                return base64_encode($mientras.$texto_cifrado);
            }
            return $mientras.$texto_cifrado;
        }

        /**
         * Decrypts (pero no autentificar) un mensaje.
         * 
         * @param cadena $mensaje - mensaje texto plano
         * @param cadena $clave - clave encriptado (raw binary expected)
         * @param booleano $codificado - ¿Esperamos una cadena codificada?
         * @return cadena
         */
        public static function decrypt($mensaje, $clave, $codificado = false)
        {
            if ($codificado) {
                $mensaje = base64_decode($mensaje, true);
                if ($mensaje === false) {
                    throw new Exception('Encriptación fallido');
                }
            }

            $tamano = openssl_cipher_iv_length(self::METHOD);
            $mientras = mb_substr($mensaje, 0, $tamano, '8bit');
            $texto_cifrado = mb_substr($mensaje, $tamano, null, '8bit');

            $texto_plano = openssl_decrypt(
                $texto_cifrado,
                self::METHOD,
                $clave,
                OPENSSL_RAW_DATA,
                $mientras
            );

            return $texto_plano;
        }
    }

$mensaje = 'Hola mundo.';
$clave = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encriptado = UnsafeCrypto::encrypt($mensaje, $clave);
$descifrado  = UnsafeCrypto::decrypt($encriptado, $clave);

echo 'Mensaje encriptada: ' . $encriptado . '<br />';
echo 'Mensaje descifrada: ' . $descifrado  . '<br />';
?>

Вывод echo, осталось бы что-то как:

Mensaje encriptada: I��Y6��� �q_��d���lO1�?�<br />
Mensaje descifrada: Hola mundo.

Шрифт:

Шрифт SO:

Заметь: в случае хотеть сохранять пароли посредством PHP и MySQL, я советую тебе, чтобы ты использовал password_hash() и password_verify()

password_hash() поверьте новый hash пароля используя алгоритм hash громко единственного чувства. password_hash() он совместим с crypt(). Следовательно, hash паролей, созданные с crypt()они могут быть использованными с password_hash().


password_verify — подтверди, что пропорциональный hash встретился с облегченным паролем.

Наблюдайте, что password_hash() возврати алгоритм, цену и соль как часть возвращенного hash. Следовательно, вся информация, которая необходима, чтобы проверять hash, включена. Это позволяет в функцию проверки подтверждать hash без необходимости хранить по отдельности информацию о соли или об алгоритме.

Больше информации в шрифте SOes:

3
ответ дан 03.12.2019, 19:12

Хорошие.

Если ты используешь Laravel, способ заверять состоит в том, чтобы использовать функции framework, всегда состоит менее обременительным.

Смотри пример с официального сайта:

Чтобы создавать Hash ты можешь делать

// obtener la contraseña desde formulario
$contrasena = Hash::make(Input::get('pass_usuario'));

Чтобы подтверждать, что password функционирует:

if (Hash::check('secret', $hashedPassword)){
    // The passwords match...
}

Пример enrolamiento был бы

function login (Request $request){
    $idUsuario = $request['id_usuario'];
    $passUsuario = $request['pass_usuario'];

    $usuario = Usuarios::find ($idUsuario);

    // se usar la contraseña y el hash como parametros
    if (Hash::check($passUsuario, $usuario->CONTRASENA)) {

          // usar Session para mantener la sesion del usuario (esto es un ejemplo solamente :P)
          Session::put('id', $idUsuario);

          // redirigir al inicio
          return redirect('inicio/');
    } else {
          // devolver error al cliente
          return response()->json(array('error' => 'No se ha podido enrolar'));
    }
}

Я должен отмечать, что, чтобы добавлять эти функции, ты должен создавать зерно в файле конфигурации .env следующего способа:

 php artisan key:generate

Также ты должен добавлять в заголовок:

use Hash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Session;

Документация Session будь в Официальном Сайте
Документация Redirect будь в официальном Сайте
Документация Response()->json будь в официальном Сайте

Сейчас, если ты спросишь у меня, - правильное Шифрование почта ли, я скажу тебе, что нет. Где ты думаешь сохранять пароли, с которыми они шифруются? В той же базе данных? Как ты будешь манипулировать разрешениями, чтобы соглашаться на эти пароли?
Я думаю, что шифровать Электронные почты они только способствуют тому, чтобы твое приложение нуждалось в большем количестве ресурсов в момент соглашения, кроме которого они способствуют тому, чтобы твое приложение было меньшим количеством mantenible.

Смотри эти ответы в Стакковерфлов Инглес: Is it worth encrypting электронная почта addresses in the был датирован?

2
ответ дан 03.12.2019, 19:12

Не существует никакая проблема, если произведенная цепь не равна каждый раз, когда он производится, всякий раз когда у тебя был один key возможно desencriptarla первоначальной цепи. Смотри следующий код:

<?php
function encriptar($key='', $cadena = ''){
    $iv = mcrypt_create_iv(
        mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
        MCRYPT_DEV_URANDOM
        );

    $encrypted = base64_encode(
        $iv .
        mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            hash('sha256', $key, true),
            $cadena,
            MCRYPT_MODE_CBC,
            $iv
        )
    );
    return $encrypted;
}


function desencriptar($key='', $cadena = ''){
    $data = base64_decode($cadena);
    $iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

    $decrypted = rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            hash('sha256', $key, true),
            substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
            MCRYPT_MODE_CBC,
            $iv
        ),
        "\0"
    );
    return $decrypted;
}

$key = 'key para encriptar';
$string = 'stack overflow';
echo "Datos oginales:<br>key: ".$key."<br>cadena:".$string;
$encryptedstring = encriptar($key, $string);
echo "<br><br>cadena encriptada:".$encryptedstring;
$decryptedstring = desencriptar($key, $encryptedstring);
echo "<br><br>cadena desencriptada:".$decryptedstring;
?>

Однако это не хорошая практика для encriptar пароли, кроме того, что - старый метод (хотя он не deprecado).

Если то, что ты хочешь, encriptar цепь, и всегда получать тот же результат в encriptar, протестируй следующее:

$string = 'stack overflow';
// encriptar
$hash = crypt($string, 'st');
echo "<br>encriptado: ".$hash;
// verificar
if (crypt($string, $hash) == $hash) {
    echo "<br>si, correcto!!";
}

функция crypt(str,salt) произведи всегда наличный ключ. видеть признаки здесь чтобы производить salt правильным способом

Но, если, что ты хочешь, он состоит в том, чтобы быть высоко уверен несмотря на то, что не производит всегда тот же ключ, он пытается с password_hash и password_verify. Сначала, для encriptar:

// forma 1:
$hash = password_hash('rasmuslerdorf', PASSWORD_DEFAULT);

// forma 2:
$options = [
   'cost' => 11
];
$hash = password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options);

Для desencriptar:

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

Видеть предопределенные Постоянные величины

2
ответ дан 03.12.2019, 19:12

То, что я вижу, что функция mcrypt_create_iv() поскольку он делает, что стоимость $iv будьте случайным, это трахает твою функцию, из-за которой параметр, который ты посылаешь в следующую функцию base64_encode() всегда он отличается, моя подсказка:

Манипулируй $iv как переменная глобальной конфигурации в файле как config.php и смени ее вручную на каждую установку твоей системы.

Также ты можешь производить файл config.php в течение установки и там ты производишь стоимость, у которой была бы переменная $iv.

2
ответ дан 03.12.2019, 19:12

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

Это свойство предоставляет защиту против неких типов атак, и одна из причин из-за CBC он безопаснее, чем BCE.

Как получать всегда те же результаты в encriptar цепь?

Создай различного $iv использование MCRYPT_DEV_URANDOM как псевдо-случайный чисел - генераторов.

Если он еще хочет сделать это (и только он должен делать это, если он действительно знает то, что он делает), нужно использовать тот же вектор инициализации $iv, и результат будет тем же самым.

Заметь: Но поскольку было сказано, это может компрометировать безопасность системы.

Добавочная точка: Вы можете хранить в Вашей базе данных, в инстанции класса, или хранить ее как префикс / суффикс последнего hash.

Хотя Вы должны вновь не использовать $iv концы безопасности...

Второй выбор: Состоит в том, чтобы производить единственный раз и сохранять это в базе данных и вновь использовать это.

function getIv($database) {
    // fictive database abstraction layer
    $iv = $database->fetchIv();
    if (!$iv) {
        $iv = mcrypt_create_iv(
            mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), 
            MCRYPT_DEV_URANDOM
        );
        $database->saveIv($iv);
    }

    return $iv;
}

// in your class

public function encriptar($string) {
    $encrypted = base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                                                    hash('sha256', getKey(), true), 
                                                    $string, MCRYPT_MODE_CBC, getIv()));    
    return $encrypted;
}
5
ответ дан 03.12.2019, 19:12

Короткий ответ

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

Длинный ответ

Проблема состоит в том, что всегда меня возвращает отличная стоимость даже добавляя ту же цепь.

Это ожидаемое поведение. Определив MCRYPT_RIJNDAEL_128 и MCRYPT_MODE_CBC ты используешь криптографию AES совместимый, в способе CBC. Этот способ включает / требует вектор инициализации случайный, известный в качестве IV (которые в твоем коде ты инициализируешь в первой линии). Это разум, из-за которого стоимость всегда различная, из-за случайного вектора.

Способ CBC (или cipher block chaining) используй один IV после того, как инициализирует криптографию (и расшифровка), что делает гораздо более надежным алгоритм. IV это не число random бессмысленно, ты должен иметь вектор инициализации в другую сторону (шифровальщик) для того, чтобы он смог делать расшифровку. Это только делает в немного более сложный ключ, так как он обладает двумя частями, симметричный ключ (ключ AES) и вектор инициализации ( IV).

introducir la descripción de la imagen aquí

Это разум, из-за которого твой метод "прилагает" IV в шифрованную стоимость, потому что потом он требуется другой стороны, чтобы инициализировать расшифровку.

Как я могу делать для того, чтобы это всегда была та же стоимость?

Моя рекомендация состоит в том, чтобы ты это не сделал, не важно, чтобы стоимость не была равна. Самое важное состоит в том, чтобы криптография была надежной.

Лучшее состояло бы в том, чтобы ты продолжил использовать то, что ты используешь: CBC и пошли IV и что другая сторона инициализировала вектор apropiadamente и расшифровывала контент.

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

Чтобы завершать ответ, способ ECB encripta каждый блок (что они той же длины, что и ключ) независимой формы. Это означает, что, если бы encriptas электронная почта, все те сообщения, которые происходят от того же шрифта, однажды encriptados начались с той же последовательностью encriptada!!! (так как все начнутся с блоком: From: <juan.perez@gmail.com>\n, производя по крайней мере воспринимаемый главный файл любую заинтересованную сторону в Вашем контенте.

introducir la descripción de la imagen aquí

Другие способы (как CBC) что включают один IV (или intialization вектор) случайный, encriptan каждый блок используя исходит из предыдущего блока, а следовательно они гораздо более надежные. В этом изображении может быть увиденным различие между способом ECB и любой другой способ, который включает зависимость от случая.

introducir la descripción de la imagen aquí

Мас Информасион:

https://crypto.stackexchange.com / questions / 967/aes-in-ecb-mode-weakness

https://crypto.stackexchange.com / questions / 20941/why-shouldnt-i-use-ecb-encryption

9
ответ дан 03.12.2019, 19:12
  • 1
    поскольку он замечает, в CBC ты можешь использовать IV недействительного, который будет способствовать тому, чтобы он всегда возвратил ту же стоимость, но это не является очень рекомендуемым также, из-за которого он уменьшает конечную силу криптографии. –  26.12.2016, 22:39
  • 2
    очень хорошая explicació n!! –  29.12.2016, 18:05
  • 3
    explicació n очень полная, в которой остается очень ясная причина в системе encriptació n не deberí чтобы возвращать ту же encriptació n для той же цепи. +1 –  29.12.2016, 23:47
  • 4
    Очень хорошая explicació n. +1 –  01.01.2017, 10:07

Мы идем по частям:

  1. Твой код не показывает форму, в которой производится ключ getKey()
  2. Ты используешь функцию криптографии, которая использует сектор инициализации $iv
  3. MCRYPT_DEV_URANDOM произведи случайные данные каждый раз, когда ты звонишь в функцию encriptar()

Сейчас, чтобы мочь получать тот же string, всегда ты должен использовать всегда ту же игру $iv, ключ и текст. Ты можешь производить $iv в base64 и видеть это на экране с print_r или echo, потом ты бы это использовал в твоей функции в чем-то как:

$iv = base64_decode('230487298384920weuiw'); //esta sería

От этой формы всегда ты получишь тот же результат в шифрование твой текст.

В зависимости от приложения, что ты дал это ему, он может или не быть хорошим, если ты шифруешь пароли, я предлагаю тебе проверять функцию password_hash () который помогает bcrypt, потом ты можешь использовать password_verify чтобы знать, ли твой password хорошо или нет.

Я надеюсь, что он подает тебя...

5
ответ дан 03.12.2019, 19:12
  • 1
    Использовать того же самого IV во всех прошлые уменьшает мощь алгоритма и считается плохой практикой. Не будь должен рекомендоваться без aclaració n, который позволила брать decisió n правильная, если / не использовать IV установленного. –  26.12.2016, 23:11
  • 2
    Это плохая одна prá ctica в общем, но OP está прося это... Ademá s я довожу до сведения, что он зависит от использования этого алгоритма será или плохая не одна prá ctica, так как все зависит от уровня безопасности, которой хотели бы достигнуть. –  27.12.2016, 00:22