【问题标题】:Problem encrypting/encoding URL variable问题加密/编码 URL 变量
【发布时间】:2009-12-29 08:21:39
【问题描述】:

我有一个类采用这种格式的字符串:

000067000000000012620060324b38e2cab3353

,加密字符串,然后将其作为获取变量附加到 URL 中。

进行加密的类有一个如下所示的函数:

private function _code_encryption($enc_type,$a_string){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);                          

    if($enc_type == self::ENCRYPT_STRING){
       //encrypt then return base64 encoded
       $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $a_string, MCRYPT_MODE_CBC, $iv);
       return base64_encode($encrypted);
    }elseif($enc_type == self::DECRYPT_STRING){
       $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, base64_decode($a_string), MCRYPT_MODE_CBC, $iv);
        return trim($decrypted);
    }
}

当字符串被加密时,我对值进行 urlencode 并将其添加到 url,就像 url 看起来像 "https://secure.mysite.com/index.php?action=someaction&transfer_code=XXXXX 其中 XXXX 是 urlencoded 加密字符串。

现在,当解析和处理 url 时,$_GET['transfer_code'] 的值被传递到上面的 _code_encryption 函数中,但没有返回正确解密的值,而是返回我的浏览器无法呈现的乱码。我用于加密/解密的密钥长度是否有要求?我尝试了类似

$key = hash('sha256',self::AUTH_ENCRYPTION_KEY,true);

但这也没用……

另外,我没有对 $_GET['transfer_code'] 变量进行 urldecoding,因为获取 vars 的 php 手册页状态已经被 urlencoded...

我应该在加密/base64_encoding 之前对字母数字字符串进行 UTF-8 编码,还是会有什么不同?

【问题讨论】:

    标签: php url encryption encoding


    【解决方案1】:

    您使用随机 IV 进行加密,并使用 不同 随机 IV 进行解密。解密后的字符串永远不会与原始字符串匹配。要正确解密原始字符串,您必须使用加密期间使用的相同 IV。通常这是通过在加密字符串前面加上 IV 来实现的。在解密时,您必须首先从值中提取 IV,使用该值初始化密钥,然后使用正确初始化的密钥解密其余部分。

    我没有解析器来验证这一点,但它应该是这样的:

    private function _code_encryption($enc_type,$a_string){
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
     if($enc_type == self::ENCRYPT_STRING){
      //encrypt then return base64 encoded
      $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
      $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $a_string, MCRYPT_MODE_CBC, $iv);
      return base64_encode($iv.$encrypted);
     } elseif ($enc_type == self::DECRYPT_STRING){
      $decoded = base64_decode($a_string);
      $iv = substr($decoded,0,$iv_size);
      $cipher = substr($decoded,$iv_size);
      $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $cipher, MCRYPT_MODE_CBC, $iv);
      return trim($decrypted);
     }
    }
    

    【讨论】:

    • 您是否有意跳过 iv 的第一个字符( substr($decoded,1,$iv_size) )?我认为一切正常(从 char 0 中提取 IV,而不是 1),但结果好坏参半。例如,加密/编码这个字符串“67:1262031751:4b38e2cab2353”效果很好,但这个“24:1262031777:4b38e2cab2353”根本不起作用,并返回一个 64 字符的假字符字符串。
    • 不,id 没有故意跳过第一个字符。我只是不记得是基于 0 还是基于 1。
    • 如果某些字符串有效,则不能确保您的 base64 编码/解码正确。 base64 用“=”填充输出,如果 urlencode/decode 去除了“=”,则 base64 编码/解码已损坏,结果是密码已损坏。您将一一进行并在每个步骤中验证反向操作是否有效(加密和验证后解密输出,编码后解码和验证等)。
    • 原来 urlencoding 很好地保留了“=”符号,但空格被转换为 %2B,而不是“+”。问题解决了。
    • 我可能有同样的问题。你是如何解决加号和空格的问题的?我尝试同时使用 realurlencode 和 urlencode 都没有成功。
    猜你喜欢
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2015-06-20
    • 2011-10-14
    • 2010-11-14
    相关资源
    最近更新 更多