PHP mcrypt 相同的密钥 + base64 + urlencode = 不同的值

PHP mcrypt same key + base64 + urlencode = different values

我正在尝试使用 mcrypt 加密一个 PHP 站点上的值并在另一个站点上解密它。有时它有效(大约 80% 的时间),有时它不起作用。 现在我发现用相同的密钥加密相同的值时,加密的文本是不同的。这怎么可能? 我错过了什么?

这里是加密代码:

# key is always the same
$key = "mysimplekey";

# text is always the same
$plaintext = "text_to_encrypt";

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);

$ciphertext = $iv . $ciphertext;

$ciphertext_base64 = base64_encode($ciphertext);
$ciphertext_url = rawurlencode($ciphertext_base64);

# gives different values for the same key & encryption text:                    
echo $ciphertext_url;

解密代码:

$key = 'mysimplekey';

$ciphertext_dec = base64_decode($_REQUEST['u']);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);

# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$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);

# may remove 00h valued characters from end of plain text
$ciphertext_dec = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec));

我怀疑 rawurlencode() 和由 PHP 完成的用于填充 $_REQUEST 数组的解码的组合正在破坏你的 ciphertext/iv。

更新:我测试了你的代码,它在我的实现中按预期工作。也许在您的实现中,编码文本正在客户端被修改。

太棒了。

这个问题显然不是我在问题本身中提到的。 对不起。

独立的这应该像@ChrisRibe 在他的回答中测试过的那样工作。

这个特殊情况下的问题——我在问题中没有提到——是,整个 URL 也被 url 编码,因为它作为参数传递给另一个 url(即 html2pdf.it 服务器)。因此,如果加密的 base64 编码文本中没有特殊的 url 保留字符,它就可以工作 - 但如果有任何 url 保留字符,它当然不起作用!

解决方案:

我不再对 base64 编码的加密文本使用 rawurlencode,而是用我自己的函数替换导致 urls 问题的 3 个符号,就像在这个 Whosebug 问题中回答的那样: Passing base64 encoded strings in URL

function base64_url_encode($input) {
 return strtr(base64_encode($input), '+/=', '-_~');
}

function base64_url_decode($input) {
 return base64_decode(strtr($input, '-_~', '+/='));
}