通过GET参数传递原始的base64编码字符串是否安全?
还有其他的base64规范。(具体请参见此处的表格)但基本上您需要65个字符来进行编码:26个小写字母+26个大写字母+10个数字=62。
您需要两个额外的['+', '/']以及一个填充字符'='。但它们都不适合URL,因此只需为它们使用不同的字符即可解决问题。从上面的表格中选择的标准字符是['-', '_'],但只要您解码它们的方式相同,并且不需要与他人共享,则可以使用其他字符。
我建议您编写自己的辅助程序。例如php手册页面上的评论中提供的这些帮助程序:
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '._-');
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '._-', '+/='));
}
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
(['
而不是{["
)可以实现更大的减少。 - rinogo@joeshmo,或者你可以直接对base64编码后的字符串进行urlencode,这样做与使用帮助函数是完全相同的,但不需要额外使用两个函数。
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
字符作为 URL 路径而不是 GET 参数传递,请小心处理。如果你不在两侧替换 /
,它会改变你的路径。 - NeverEndingQueue简介 我倾向于发表一些澄清,因为这里的一些答案有点误导(如果不是错误的话)。
答案是否定的,您不能只通过URL查询字符串传递base64编码的参数,因为加号会在$_GET全局数组内转换为空格。换句话说,如果您发送了test.php?myVar=stringwith+sign 到
//test.php
print $_GET['myVar'];
结果将是:
带符号字符串
解决这个问题的简单方法是在将base64字符串添加到查询字符串之前使用urlencode()
函数对其进行编码,以转义+、=和/字符为%##代码。
例如,urlencode("带符号字符串")
返回 带符号字符串
当您处理操作时,PHP会自动处理解码查询字符串,并在填充 $_GET 全局变量时完成该过程。 例如,如果我发送test.php?myVar=带符号字符串的编码
//test.php
print $_GET['myVar'];
结果为:
stringwith+sign
您不需要对返回的$_GET字符串进行urldecode()处理,因为加号(+)会被转换为空格。
换句话说,如果我向同一目标发送test.php?myVar=stringwith%2Bsign
//test.php
$string = urldecode($_GET['myVar']);
print $string;
结果出现了意外情况:
带符号的字符串
可以使用rawurldecode()
函数对输入进行安全的解码,但这是多余和不必要的。
<br>
,所以无需输入太多HTML。希望这可以帮助您,我稍微编辑了一下您的答案以进一步完善它。 - hakre是和不是。
Base64的基本字符集在某些情况下可能与URL中使用的传统约定冲突。但是,许多Base64实现允许您更改字符集以更好地匹配URL,甚至带有一个(例如Python的urlsafe_b64encode()
)。
您可能面临的另一个问题是URL长度的限制,或者说——缺乏此类限制。因为标准没有规定任何最大长度,所以处理HTTP协议的浏览器、服务器、库和其他软件可能会定义自己的限制。
这是一个你可以尝试的base64url编码,它只是上面joeshmo代码的扩展。
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
Base64.getUrlEncoder().withoutPadding().encodeToString()
编码的数据。 - user520458我不认为这是安全的,因为例如在原始base64中使用了“=”字符,并且还用于区分HTTP GET请求中的参数和值。
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 安全编码,例如 Python 中的 base64.urlsafe_b64encode(...)
,下面的代码对我来说可行了 100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}
urlencode
,就像 rodrigo-silveira 的回答建议的那样。创建两个新函数只是为了在 URL 长度中节省一些字符,这就像从窗户进入你的房子,而不是使用门一样。 - Marco Demaio