繁体   English   中英

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

[英]Passing base64 encoded strings in URL

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

还有其他 base64 规范。 (有关详细信息,请参见此处的表格)。 但本质上你需要 65 个字符来编码:26 个小写字母 + 26 个大写字母 + 10 个数字 = 62。

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

我建议只编写自己的助手。 就像base64_encode 的 php 手册页上的评论一样:

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

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

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

有效的 base64 字符如下。

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

@joeshmo 或者不用编写辅助函数,您可以只对 base64 编码的字符串进行 urlencode。 这将做与您的辅助函数完全相同的事情,但不需要两个额外的函数。

$str = 'Some String';

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

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

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

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

结果将是:
stringwith sign

解决此问题的简单方法是在将 base64 字符串添加到查询字符串之前简单地对 base64 字符串进行urlencode()以将 +、= 和 / 字符转义为 %## 代码。 例如, urlencode("stringwith+sign")返回stringwith%2Bsign

当您处理该操作时,PHP 负责在填充 $_GET 全局变量时自动解码查询字符串。 例如,如果我发送test.php?myVar=stringwith%2Bsign

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

结果是:
stringwith+sign

不想对返回的 $_GET 字符串进行urldecode() ,因为 + 将被转换为空格。
换句话说,如果我发送相同的test.php?myVar=stringwith%2Bsign

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

结果出乎意料:
stringwith sign

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

是和不是。

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));
}

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

如果你安装了 sodium 扩展并且需要对二进制数据进行编码,你可以使用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 和/oor 查询字符串长度。

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

对于 url 安全编码,例如 Python 中的base64.urlsafe_b64encode(...)下面的代码,对我 100% 有效

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

是的,它总是安全的。 当然base64包含: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=但是base64编码的字符串通常没有+ +将被转换为空格,导致错误的解码字符串。 /在get参数对中是安全的。 =始终位于base64编码字符串的末尾,服务器端可以直接解析=

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM