我的加密/解密解决方案无法正常工作

时间:2014-07-09 23:32:00

标签: php mcrypt

我试图弄清楚我的加密/解密代码有什么问题,但我似乎在谷歌搜索与我类似的问题时陷入了死胡同。

这是我的两个函数的PHP代码,但我先解释一下。这些工作如何通过使用salt,用户的密码以及他们上次登录的unix纪元时间(或者如果他们之前从未登录过时的当前纪元时间)来创建加密密码。

现在我正在测试代码以查看它是否有效,然后再将其挂钩到我的其余PHP代码中。传递给函数的密码是Test,它使用time()来提供时间,然后在加密过程中将该值存储到全局变量中,这样我就不必在测试时将它存储到数据库中。

在一个SO线程this one中,我在创建IV时使用MCRYPT_RAND读取,然后不保存生成的IV意味着解密将永远不会起作用,因为如果您重新调用mcrypt_create_iv来创建IV将会有所不同解密期间的IV。所以我也为IV制作了全局,并在解密过程中尝试了它,但它仍然没有正确解密。下面的代码反映了这种变化。

  //Encrypt the user's password for storing in database 
function encrypt($password, $id)
{
    echo "Function: encrypt \n"; //For debugging

    $salt2 = getTime($id);

    $salt1 = 'akey'; //Changed for security purposes

    global $cur_iv;

    $key = substr(hash('sha256',$salt1.$password.$salt2),0,32);
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
    $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $password, MCRYPT_MODE_ECB, $iv));

    $cur_iv = $iv;

    echo $encrypted;
    echo "\n";

    global $cur_time;

    $cur_time = $salt2; 

    return $encrypted;
}

//Decrypt the user's password for loggin checking
function decrypt($password,$id)
{
    echo "Function: decrypt \n"; //For debugging

    //$salt2 = getTime($id);
    global $cur_time;
    $salt2 = $cur_time;

    $salt1 = 'akey'; //Changed for security purposes

    global $cur_iv;

    $key = substr(hash('sha256',$salt1.$password.$salt2),0,32);
    $iv = $cur_iv;
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($pass), MCRYPT_MODE_ECB, $iv);

    echo $decrypted;
    echo "\n";

    return $decrypted;
}

加密这是密码的样子:xgr5YB0vHwJAkjkqwTl6rnZMjbZL0qmLE4D8JXDT1rM =

但解密它看起来像这样:NÞÚ±=º)cz_öUñŽP'è8Åáó»d- +ÒAÐ

编辑2:

这是Saikios要求的getTime函数:

//Use the last login time for part of the encryption salt to ensure more secure hashing
function getTime($id)
{
    global $sql;

    echo "Function: getTime \n"; //For debugging

    if ($salt_stmt = $sql->prepare("Select Last_Login From login_log Where User_ID = ?;"))
    {
        $salt_stmt->bind_param('i',$id);
        $salt_stmt->execute();
        $salt_stmt->store_result();
        $salt_stmt->bind_result($time);
        $salt_stmt->fetch();

        if ($salt_stmt->num_rows < 1)
        {
            echo "No last login \n";

            $time = time();
        }

        else
        {   
            echo "Last Login Time: ".$time."\n";            
        }

        return $time;

    }

    else
    {
        echo "Error: ".$sql->error; 
    }
}

2 个答案:

答案 0 :(得分:1)

我知道你想使用自己的功能,但为什么不用它作为基础(由Naveen S. Nayak,不是我http://naveensnayak.wordpress.com/2013/03/12/simple-php-encrypt-and-decrypt/),

function encrypt_decrypt($action, $string) {
    $output = false;

    $encrypt_method = "AES-256-CBC";
    $secret_key = 'This is my secret key';
    $secret_iv = 'This is my secret iv';

    // hash
    $key = hash('sha256', $secret_key);

    // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
    $iv = substr(hash('sha256', $secret_iv), 0, 16);

    if( $action == 'encrypt' ) {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    }
    else if( $action == 'decrypt' ){
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }

    return $output;
}

$plain_txt = "This is my plain text";
echo "Plain Text = $plain_txt\n";

$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n";

$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n";

if( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";

echo "\n";

(关于如何传递变量似乎存在问题)

----- ---------- OLD 我没有getTime函数,但....

加密更改

$cur_time = salt2;  

$cur_time = $salt2;

答案 1 :(得分:1)

在这里你可以使用我的,但请不要使用md5('密码')作为你的密钥:)

function symEncode($decrypted, $key){
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);

        $iv_base64 = rtrim(base64_encode($iv), '=');
        // Encrypt $decrypted and an MD5 of $decrypted using $key.  MD5 is fine to use here because it's just to verify successful decryption.
        $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $decrypted . md5($decrypted), MCRYPT_MODE_CBC, $iv));
        // We're done!
        return $iv_base64 . $encrypted;
    }

function symDecode($encrypted, $key){
    // Retrieve $iv which is the first 43 characters plus ==, base64_decoded.
    $iv = base64_decode(substr($encrypted, 0, 43) . '==');
    // Remove $iv from $encrypted.
    $encrypted = substr($encrypted, 43);
    // Decrypt the data.  rtrim won't corrupt the data because the last 32 characters are the md5 hash; thus any \0 character has to be padding.
    //pre_var_export(debug_backtrace(false));
    $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv), "\0\4");
    // Retrieve $hash which is the last 32 characters of $decrypted.
    $hash = substr($decrypted, -32);
    // Remove the last 32 characters from $decrypted.
    $decrypted = substr($decrypted, 0, -32);
    // Integrity check.  If this fails, either the data is corrupted, or the password/salt was incorrect.
    if (md5($decrypted) != $hash){
        die('failed');
    }
    // Yay!
    return $decrypted;
}


$key = md5('password');
$decrypted = 'some important data';

$encrypted = symEncode($decrypted, $key);
echo $encrypted . '<br>';  
echo symDecode($encrypted, $key);

输出:

43p2K/0RG20fnuHEx2B3q18KM7FpGLRfb+BwFfYt1V1mMr5PsAroum/jEeO6LonmC4T9N6QQQfOfMwTmbyNRFG4Qi5imGPAq0LsbgYJHWZ50Lw0C7uSRDb7CC1I4Uv1/LFQ==

some important data

$key = md5('password');
        $decrypted = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc bibendum augue et vehicula adipiscing. Maecenas interdum, enim a accumsan convallis, est urna posuere mauris, eu ultricies lacus enim at justo. Vestibulum auctor sed elit a';

输出:

431nn42sTg7/XlGw4nAw3aFmMiYOnOQCVMjs4xY2m3DNcgiTFyqs1scG3VCxx/srEV9OGePqD4qrV1AectSqIWCSjYCinsS1jThEL9OuxxXeaGCbycXybdeMUCz1gKJZ5zVegMjqcWzyaX6/32sMs+Mh/NO+e9uh9lOdgmpofHEUWc9m4n6yziX2TllDKxbbADogeRjfW5SzzhaR/bx24kV9/44QhMRA1IJwFteHzCI9qTLGL/586MziGUVbZJe9Y9TqhiWEAIgJ0tO0iWVGMBYV1ibwv8VzDr0LcN7qL4345ryoQ3hjrixpLnBNKewKhbCB/4EkJ7+FD1nUyHOZLEyhi52oMqs/uDv1qSk/Pgk+Poku8DCd5ZbxbAJQG6Wp8BlZzfXOak1tyTKaJUsRziM/zmaXvpYrq3WWJti4cQaxc

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc bibendum augue et vehicula adipiscing. Maecenas interdum, enim a accumsan convallis, est urna posuere mauris, eu ultricies lacus enim at justo. Vestibulum auctor sed elit a