使用mcrypt加密/解密 [英] Encrypt/Decrypt using mcrypt

查看:124
本文介绍了使用mcrypt加密/解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用以下策略实现加密和解密,但最终以随机字符结尾。

  class Crypt {

public static function encrypt($ string,$ account){
//创建一个用于CBC编码的随机初始化向量
$ iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC);
$ iv = mcrypt_create_iv($ iv_size,MCRYPT_RAND);

$ key = pack('H *',$ account。$ account);

$ output = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$ key,$ string,MCRYPT_MODE_CBC,$ iv);
$ output = $ iv。 $输出;
$ output = base64_encode($ output);
$ output = urlencode($ output);

return $ output;
}

public static function decrypt($ token,$ account){
$ ciphertext_dec = base64_decode($ token);

//检索IV,iv_size应该使用mcrypt_get_iv_size()
$ iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC)创建;
$ iv_dec = substr($ ciphertext_dec,0,$ iv_size);

//检索密文(除前面$ iv_size之外的所有内容)
$ ciphertext_dec = substr($ ciphertext_dec,$ iv_size);

$ key = pack('H *',$ account。$ account);

$ token = urldecode($ token);

$ output = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$ key,$ ciphertext_dec,MCRYPT_MODE_CBC,$ iv_dec);
$ output = rtrim($ output,);
return $ output;
}

}

无法获取准确的值有时它解密,但是我看到一些垃圾值,但是大多只是随机字符。

  $ a = \Crypt :: encrypt (MyPassword,1974246e); 
echo \Crypt :: decrypt($ a,1974246e);






讨论后编辑



  class Crypt {

public static function encrypt($ data,$ passphrase){
$ iv_size = mcrypt_get_iv_size MCRYPT_RIJNDAEL_256,MCRYPT_MODE_CBC); //创建一个用于CBC编码的随机初始化向量
$ iv = mcrypt_create_iv($ iv_size,MCRYPT_RAND);
$ key = pack('H *',$ passphrase。$ passphrase);
return base64_encode($ iv。mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$ key,$ data,MCRYPT_MODE_CBC,$ iv));
}

public static function decrypt($ data,$ passphrase){
$ data = base64_decode($ data);
$ iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,MCRYPT_MODE_CBC); //检索IV,iv_size应该使用mcrypt_get_iv_size()
$ iv = substr($ data,0,$ iv_size)创建;
$ data = substr($ data,$ iv_size); //检索密文(除前面的$ iv_size之外的所有内容)
$ key = pack('H *',$ passphrase。$ passphrase);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$ key,$ data,MCRYPT_MODE_CBC,$ iv),chr(0));
}
}

用法:

  $ pass =MyPassword *& ^ *& ^(*& ^(; 
$ token = \Crypt :: encrypt $ pass $$$$$$$$$$$$$$$$$$$$


解决方案


  1. 不要urlencode不必要的。

  2. 修剪NULL字节,而不是空字符串: rtrim($ str,chr(0)); 您可能希望将源字符串长度保存在加密结果中,因此您不会 rtrim()太多。)



  3. 为什么 pack('H *',$ account) for $ key ?也是不必要的。



    Rijndael 128使用16个字节的键(128位),所以确保你的键至少那么长:

      $ key = $ account。$ account 

    会做,但这显然是有争议的($ code> mcrypt 会做这样的事情,如果它太短。)如果每个帐户都有自己的密码,那将是好的。 (甚至更多的是结合一个应用程序秘密,但细节。)



    rtrim() with chr(0)很好,很可能是因为你的源字符串不会拖尾NUL个字节。



    我通常使用这些en / decrypt函数,或者类似的,但是这些有一个静态的秘密/密钥,所以你的更好。



    要向客户端发送加密令牌:

      $ enc_token = Crypt :: encrypt($ token,$ key); 
    // $ enc_token可能包含`/`和`+`和`=`
    $ url ='page.php?token ='。进行urlencode($ enc_token);


    Trying to achieve encrypting and decryption using following strategy, but ending up with random characters mostly.

    class Crypt {
    
    public static function encrypt($string, $account) {
        // create a random initialization vector to use with CBC encoding
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    
        $key = pack('H*', $account . $account);
    
        $output = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $iv);
        $output = $iv . $output;
        $output = base64_encode($output);
        $output = urlencode($output);
    
        return $output;
    }
    
    public static function decrypt($token, $account) {
        $ciphertext_dec = base64_decode($token);
    
        // retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $iv_dec = substr($ciphertext_dec, 0, $iv_size);
    
        // retrieves the cipher text (everything except the $iv_size in the front)
        $ciphertext_dec = substr($ciphertext_dec, $iv_size);
    
        $key = pack('H*', $account . $account);
    
        $token = urldecode($token);
    
        $output = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
        $output = rtrim($output, "");
        return $output;
    }
    
       }
    

    Can't get exact values back, sometimes it decrypts but I see some garbage values, but mostly just random characters.

    $a = \Crypt::encrypt("MyPassword", "1974246e");
    echo \Crypt::decrypt($a, "1974246e");
    


    Edits after the discussion

    class Crypt {
    
    public static function encrypt($data, $passphrase) {
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); //create a random initialization vector to use with CBC encoding
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $key = pack('H*', $passphrase . $passphrase);
        return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv));
    }
    
    public static function decrypt($data, $passphrase) {
        $data = base64_decode($data);
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); //retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
        $iv = substr($data, 0, $iv_size);
        $data = substr($data, $iv_size); //retrieves the cipher text (everything except the $iv_size in the front)
        $key = pack('H*', $passphrase . $passphrase);
        return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv), chr(0));
    }
    }
    

    Usage:

    $pass = "MyPassword*&^*&^(*&^(";
    $token = \Crypt::encrypt($pass, "1974246e8e8a479bb0233495e8a3ed12");
    $answer = \Crypt::decrypt($token, "1974246e8e8a479bb0233495e8a3ed12");
    echo $answer == $pass ? "yes" : "no";
    

    解决方案

    1. Don't urlencode. Unnecessary.
    2. trim for NULL bytes, not empty strings: rtrim($str, chr(0)); (Instead, you might want to save the source string length in the encrypted result too, so you won't rtrim() too much.)

    Why pack('H*', $account) for $key? Also unnecessary.

    Rijndael 128 uses 16 byte keys (128 bits), so make sure your key is at least that long:

    $key = $account . $account
    

    will do, but it obviously imperfect. (mcrypt will do something like that if it's too short.) If every account had its own passphrase, that would be good. (Even more so in combination with an app secret, but details.)

    rtrim() with chr(0) is fine, very probably, because your source string won't have trailing NUL bytes.

    I usually use these en/decrypt functions, or alike, but these have a static secret/key, so yours is better.

    To send an encrypted token to the client:

    $enc_token = Crypt::encrypt($token, $key);
    // $enc_token might contain `/` and `+` and `=`
    $url = 'page.php?token=' . urlencode($enc_token);
    

    这篇关于使用mcrypt加密/解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆