通过GET参数传递原始base64编码的字符串是否安全?
答案 0 :(得分:251)
还有其他base64规格。 (具体见表here)。但基本上你需要65个字符来编码:26小写+ 26大写+ 10位= 62。
你还需要两个['+','/']和一个填充字符'='。但是它们都不是网友友好的,所以只是为它们使用不同的字符并且你已经设置好了。上图中的标准值是[' - ','_'],但只要您对其进行解码,就可以使用其他字符,而不需要与其他字符共享。
我建议你自己写一个帮手。与php manual page for base64_encode上的评论相似:
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '._-');
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '._-', '+/='));
}
答案 1 :(得分:181)
不,您需要对其进行url-encode,因为base64字符串可以包含“+”,“=”和“/”字符,这些字符可能会改变数据的含义 - 看起来像子文件夹。
有效的base64字符在下面。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
答案 2 :(得分:68)
@joeshmo或者不是编写辅助函数,而是可以对base64编码的字符串进行urlencode。这与你的辅助函数完全相同,但不需要两个额外的函数。
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
答案 3 :(得分:38)
介绍性说明我倾向于发表一些澄清,因为这里的一些答案有点误导(如果不是不正确的话)。
答案是否,您不能简单地在URL查询字符串中传递base64编码参数,因为加号会在$ _GET全局数组中转换为SPACE。换句话说,如果您将 test.php?myVar = stringwith + sign 发送到
//test.php
print $_GET['myVar'];
结果将是:
stringwith sign
解决此问题的简单方法是在将base64字符串添加到查询字符串之前简单urlencode()
将其转义为将%,=和/字符转义为%##代码。
例如,urlencode("stringwith+sign")
会返回stringwith%2Bsign
当您处理操作时,PHP会在填充$ _GET全局时自动解码查询字符串。 例如,如果我将 test.php?myVar = stringwith%2Bsign 发送到
//test.php
print $_GET['myVar'];
结果将是:
stringwith+sign
你不想要urldecode()
返回的$ _GET字符串,因为+将被转换为空格。
换句话说,如果我发送相同的 test.php?myVar = stringwith%2Bsign 到
//test.php
$string = urldecode($_GET['myVar']);
print $string;
结果出乎意料:
stringwith sign
rawurldecode()
输入是安全的,但是,这将是多余的,因此是不必要的。
答案 4 :(得分:13)
是和否。
base64的基本字符集在某些情况下可能会与URL中使用的传统约定发生冲突。但是许多base64实现允许你更改charset以更好地匹配URL,甚至可以随附一个(如Python的urlsafe_b64encode()
)。
您可能面临的另一个问题是URL长度的限制,或者更确切地说 - 缺少此类限制。由于标准没有指定任何最大长度,因此使用HTTP协议的浏览器,服务器,库和其他软件可能会定义其自身的限制。您可以查看一下这篇文章:WWW FAQs: What is the maximum length of a URL?
答案 5 :(得分:8)
它是一个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));
}
答案 6 :(得分:4)
我不认为这是安全的,因为例如“=”字符用于原始基数64,也用于区分参数与HTTP GET中的值。
答案 7 :(得分:1)
理论上,是的,只要您不超过客户端或服务器的最大URL和/或查询字符串长度。
在实践中,事情会变得有点棘手。例如,它可以在ASP.NET上触发HttpRequestValidationException,如果值恰好包含“on”并且您在尾部“==”中保留。
答案 8 :(得分:0)
对于网址安全编码,例如下面的代码中的base64.urlsafe_b64encode(...)
在Python中对我有效100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}
答案 9 :(得分:-6)
是的,它总是安全的。
当然base64包含:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
但base64编码的字符串通常没有+
。 +
将被转换为空格,导致错误的解码字符串。 /
在get参数对中是安全的。 =
始终位于base64编码字符串的末尾,服务器端可以直接解析=
。