PHP decrypt not working using mcrypt_decrypt?

2019-08-06 23:59发布

Seems that mcrypt_decrypt can't proper decrypt my string (all works fine in var_dump except when decrypting - load_decrypted value is wrong). Any help would be appreciated.

array
  'salve_plain' => string 'a:1:{s:8:"modified";i:1321974656;}' (length=34)
  'save_encrypted' => string '^ånÄc¥JŸRæk®»}J%áR–y #‡nwZX\µÚ™È§œ‘5‚<_¹M¿ÔT9k)…ª  Ø' (length=64)
  'save_encoded' => string 'XuVuxGOlA0qfUuYXa667fUoSEyXhBVKWeSAjh253EFpYXLUS2pnIp5yRNa3LgjxfuRNNv9RUOe67qmsphaoJ2A==' (length=88)

array
  'load_undecoded' => string 'XuVuxGOlA0qfUuYXa667fUoSEyXhBVKWeSAjh253EFpYXLUS2pnIp5yRNa3LgjxfuRNNv9RUOe67qmsphaoJ2A==' (length=88)
  'load_decoded' => string '^ånÄc¥JŸRæk®»}J%áR–y #‡nwZX\µÚ™È§œ‘5‚<_¹M¿ÔT9k)…ª    Ø' (length=64)
  'load_decrypted' => string '-dœÞ{*€ ¥ûü(1À�ðú-›(!*»ÓÍW¦;}' (length=34)

PHP load() function:

private function load()
{

    // Decoding
    $plain = file_get_contents($this->filename);
    $decoded = base64_decode($plain);

    // Decrypting
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->secret),
        $decoded, MCRYPT_MODE_CBC, $iv));

    // Deserializing & loading
    $this->data = unserialize($decrypted);
    var_dump(array('load_undecoded' => $plain, 'load_decoded' => $decoded,
        'load_decrypted' => $decrypted));
}

PHP save() function:

private function save()
{

    // Serialization
    $serialized = serialize($this->data);

    // Encrypting
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->secret),
        $serialized, MCRYPT_MODE_CBC, $iv);

    // Encoding & saving
    $encoded = base64_encode($encrypted);
    file_put_contents($this->filename, $encoded);

    var_dump(array('salve_plain' => $serialized,
        'save_encrypted' => $encrypted, 'save_encoded' => $encoded));

}

2条回答
我命由我不由天
2楼-- · 2019-08-07 00:30

Unfortunately you need the same $iv in both the load and the save.

// Creates a random value so that the same message encoded with the same key
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

A way around it is to use

$mode = MCRYPT_MODE_CFB;

Encrypt with

$encrypted = mcrypt_encrypt($cipher, $key, $iv . $message, $mode, $iv);

Prefix the encoded message with the IV, and then in decoding use

$decrypted = mcrypt_decrypt($cipher, $key, $encrypted, $mode, str_pad('', $iv_size));
$decrypted = substr(rtrim($decrypted, "\0"), $iv_size);

CFB has the ability to re-sync during decryption, and can use this 'recovery' feature to put your IV in.

Also, depending on the number of IVs you're creating, you may want to use urandom rather then random.

$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
查看更多
放我归山
3楼-- · 2019-08-07 00:50

You're using a different IV for encrypting and decrypting each time. So basically you're locking up your data with one key, then trying to unlock it with a completely different key.

查看更多
登录 后发表回答