通过GET参数传递原始base64编码的字符串是否安全?


当前回答

理论上,是的,只要您不超过客户端或服务器的最大url和/oor查询字符串长度。

在实践中,事情可能会变得有点棘手。例如,它可以在ASP上触发HttpRequestValidationException。如果该值碰巧包含“on”,并且您在后面留下“==”。

其他回答

如果你安装了钠扩展,需要编码二进制数据,你可以使用sodium_bin2base64函数,它允许你选择url安全的变量。

例如,编码可以这样完成:

$string = sodium_bin2base64($binData, SODIUM_BASE64_VARIANT_URLSAFE);

和解码:

$result = sodium_base642bin($base64String, SODIUM_BASE64_VARIANT_URLSAFE);

有关使用的更多信息,请查看php文档:

https://www.php.net/manual/en/function.sodium-bin2base64.php https://www.php.net/manual/en/function.sodium-base642bin.php

我倾向于发布一些澄清,因为这里的一些答案有点误导(如果不是不正确的话)。

答案是否定的,你不能简单地在URL查询字符串中传递base64编码的参数,因为加号在$_GET全局数组中被转换为空格。换句话说,如果你发送test。php?myvar# = stringwith +标志

//test.php
print $_GET['myVar'];

结果将是: stringwith标志

解决这个问题的简单方法是urlencode()您的base64字符串,然后将其添加到查询字符串中,以转义+,=和/字符为%##代码。 例如,urlencode("stringwith+sign")返回stringwith%2Bsign

在处理操作时,PHP在填充$_GET全局变量时自动解码查询字符串。 例如,如果我发送test。php?myvar# = stringwith % 2 bsign

//test.php
print $_GET['myVar'];

结果是: stringwith +标志

你不希望urldecode()返回的$_GET字符串,因为+将被转换为空格。 换句话说,如果我发送相同的test。php?myvar# = stringwith % 2 bsign

//test.php
$string = urldecode($_GET['myVar']);
print $string;

结果出乎意料: stringwith标志

rawurldecode()输入是安全的,但是,这是多余的,因此是不必要的。

对于url安全编码,如Python中的base64.urlsafe_b64encode(…),下面的代码对我来说是100%的

function base64UrlSafeEncode(string $input)
{
   return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}

或者不写辅助函数,你可以直接urlencode base64编码的字符串。这将完成与helper函数完全相同的事情,但不需要两个额外的函数。

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );

还有其他base64规范。(详见表格)。但实际上你需要65个字符来编码:26个小写字母+ 26个大写字母+ 10个数字= 62。

你还需要两个['+','/']和一个填充字符'='。但是没有一个是url友好的,所以使用不同的字符,你就设置好了。上面图表中的标准字符是['-','_'],但你可以使用其他字符,只要你对它们进行相同的解码,并且不需要与他人共享。

我建议你编写自己的助手。像下面这些来自php手册页base64_encode的注释:

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

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