在PHP中,是否有一种可靠的方法来检测字符串中的base64编码?

4

我目前正在处理一个网站,其中我的数据库中存储了混合值,并且我想找到一种解决方案来检测字符串是否为base64加密。在此帖子(Detect base64 encoding in PHP?)上受到Abhinav bhardwaj的帮助,我已经编写了以下代码:

function IsBase64($s)
{
    // Check if there are valid base64 characters
    if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s)) return false;
    // Decode the string in strict mode and check the results
    $decoded = base64_decode($s, true);
    if(false === $decoded) return false;
    // if string returned contains not printable chars
    if (0 < preg_match('/((?![[:graph:]])(?!\s)(?!\p{L}))./', $decoded, $matched)) return false;
    // Encode the string again
    if(base64_encode($decoded) != $s) return false;
    return true;
}

它只能部分地工作,例如像1234、7000、reno和其他四个字母和数字的输入值即使它们不是base64编码也会解析为true...现在我的问题是:是否有可靠的方法来进行base64检测,还是我必须保留未编码和编码表格的列表并将它们视为不同的处理? 我的计划是最终将数据(其中一些需要解密,一些不需要)合并到一个php结果对象中,并将其作为JSON文本返回。任何关于此的帮助都将不胜感激!提前感谢您! 编辑:在Yoshi的回答之后,我想把我的结论钉在顶部,以便其他寻找易于编码/解码特定数据的简单解决方案的人可以看到: 我认为更好的方法是,在数据库中将编码数据保留在特定键下,并在查询数据集结果中查找此特定键是否包含以跟踪需要解密的内容... FYI:我已将我的网站更新为这种行为,我必须承认它的效果非常好!

1
我认为你运气不佳。你提到的“假阳性”仍然是有效的base64编码。你需要判断解码后的版本是否有意义,但这可能是一个永无止境的故事,并最终可能也会导致假阳性。 - Yoshi
这正是我所想的...看起来我需要重新考虑我的数据存储逻辑,并清晰地分离编码和非编码的部分...感谢您给出明确的答案! - FyZ1K
好的,大家听着...终于我找到了一个解决这个问题的万无一失的方法。使用下面的函数来检查字符串是否是base64编码 -private function is_base64_encoded($str) { $decoded_str = base64_decode($str); $Str1 = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $decoded_str); if ($Str1!=$decoded_str || $Str1 == '') { return false; } return true; } - bilal
3个回答

2
我将发布Yoshi的评论作为最终结论:
“我认为你运气不好。你提到的假阳性仍然是有效的base64编码。你需要判断解码版本是否有意义,但这可能是一个永无止境的故事,并且最终可能也会导致假阳性。” - Yoshi

如果这是正确的答案,请将其视为正确答案。谢谢! - Ian
明天你可以接受自己的答案 - Stackoverflow - FyZ1K
我现在接受了这个帖子作为答案。抱歉耽搁了一下... - FyZ1K

2
我找到了一个完美的函数,可以检查字符串是否是有效的base64编码:
返回布尔值True或False。
function is_base64($s) {
    // Check if there are valid base64 characters
    if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s)) return false;

    // Decode the string in strict mode and check the results
    $decoded = base64_decode($s, true);
    if(false === $decoded) return false;

    // Encode the string again
    if(base64_encode($decoded) != $s) return false;

    return true;
}

感谢 Thanks #merlucin, Link

0

Base64编码字符串基本上是(A-Z)、(a-z)、(0-9)加上=填充到模4。因此,任何4的倍数字母组合都可以作为base64有效。

function IsBase64($str) {
    if (strlen($str) % 4 == 0) {
        return true;
    } else {
        return false;
    }
}

这个不行。即使它们没有进行base64编码,只要值有4个字母或数字,就会返回true... - FyZ1K
我的之前的回答太过简单了。我已经更新了我的回答,请尝试一下。 - Robin Rai
现在只是检查输入的字符串是否可以被 4 整除,并且余数为 0。此外,还会有数字值,您还必须通过其长度进行检查,因此我无法接受此作为可靠方法的答案。我认为最好的方法是,在数据库中将编码数据保留在特定密钥下,并在查询数据集结果中查找是否包含此特定密钥,以跟踪需要解密的内容... - FyZ1K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接