在URL中传递base64编码的字符串

问题描述 投票:0回答:11

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

php url string get base64
11个回答
338
投票

还有其他 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, '-_.', '+/=')); }
    

264
投票
不,您需要对其进行 url 编码,因为 base64 字符串可以包含“+”、“=”和“/”字符,这些字符可能会改变数据的含义 - 看起来像一个子文件夹。

下面是有效的 base64 字符。

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
    

97
投票
@joeshmo 或者,您可以对 Base64 编码的字符串进行 urlencode,而不是编写辅助函数。这将与您的辅助函数执行完全相同的操作,但不需要两个额外的函数。

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

49
投票

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

答案是否定的,您不能简单地在 URL 查询字符串中传递 base64 编码的参数,因为加号会转换为 $_GET 全局数组内的空格。换句话说,如果您将 test.php?myVar=stringwith+sign 发送到

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

结果将是:


stringwith sign



解决此问题的简单方法是简单地

urlencode()

您的base64字符串,然后将其添加到查询字符串中,以将+、=和/字符转义为%##代码。
例如,
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()

 是安全的,但是,它是多余的,因此没有必要。
    


19
投票
是和不是。

在某些情况下,base64 的基本字符集可能会与 URL 中使用的传统约定发生冲突。但许多 Base64 实现允许您更改字符集以更好地匹配 URL,甚至附带一个字符集(如 Python 的

urlsafe_b64encode()

)。

您可能面临的另一个问题是 URL 长度的限制,或者更确切地说 - 缺乏这样的限制。由于标准没有指定任何最大长度,因此使用 HTTP 协议的浏览器、服务器、库和其他软件可能会定义自己的限制。


13
投票
它是一个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)); }
    

5
投票
我认为这不安全,因为例如“=”字符用于原始 base 64 中,也用于区分参数和 HTTP GET 中的值。


2
投票
如果您安装了钠扩展并需要对二进制数据进行编码,您可以使用

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


1
投票
对于 url 安全编码,就像 Python 中的

base64.urlsafe_b64encode(...)

,下面的代码对我来说 100% 有效

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

0
投票
理论上可以,只要不超过客户端或服务器的最大 url 和/或查询字符串长度即可。

在实践中,事情可能会变得有点棘手。例如,如果值恰好包含“on”并且您保留了尾随的“==”,则它可能会在 ASP.NET 上触发 HttpRequestValidationException。


0
投票
对于那些使用 .NET 的用户,他们可以利用

Encode

 类的 
Decode
Base64UrlEncoder
 方法,该方法位于包 
Microsoft.IdentityModel.Tokens v6.31.0
 中。

© www.soinside.com 2019 - 2024. All rights reserved.