为什么七牛云回调签名验证不一致?如何解决?

为什么七牛云回调签名验证不一致?如何解决?

探讨七牛云回调签名验证不一致的原因及解决方案

在使用七牛云服务时,回调签名验证是一个关键的安全措施,用于确保请求的真实性和完整性。然而,有时我们可能会遇到回调签名验证不一致的问题。本文将深入探讨一个开发者在处理此类问题的过程中所遇到的具体问题,并提供一个经过改进的解决方案。

开发者在处理七牛云的回调签名验证时,使用了如下函数:

public function verifyCallbackSignature(Request $request): bool
{
    $authstr = $request->header('Authorization');
    if (empty($authstr) || strpos($authstr, "QBox ") !== 0) {
        /support/Log::debug("签名验证失败-头部格式错误", [
            'sign_content' => 'qianmingshibai'
        ]);
        return false;
    }

    $auth = explode(":", substr($authstr, 5));
    if (count($auth) !== 2 || $auth[0] !== env('QINIU_AK')) {
        /support/Log::debug("签名验证失败-AK不匹配", [
            'sign_content' => 'zhanghuAkshibai',
            'auth_count' => count($auth),
            'auth_ak' => $auth[0],
        ]);
        return false;
    }

    $data = $request->uri() . "/n" . file_get_contents('php://input');
    $re = $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true)) === $auth[1];

    /support/Log::debug("签名验证详情", [
        'data' => $data,
        'computed_sign' => $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true)),
        'received_sign' => $auth[1],
    ]);

    return $re;
}
登录后复制

开发者发现即使尝试使用body参数,回调签名始终与七牛云传来的签名不一致。经过分析,发现问题主要出在以下几个方面:

  1. 请求体的获取:在原始代码中,$data的构建方法可能不够完整,尤其是对于带有查询字符串的URL。
  2. 签名计算:原始代码中的签名计算方法和七牛云的要求可能有所出入。

为了解决这个问题,开发者对原始函数进行了如下改进:

public function verifyCallbackSignature(Request $request): bool
{
    $authstr = $request->header('Authorization');
    if (empty($authstr) || strpos($authstr, "QBox ") !== 0) {
        /support/Log::debug("签名验证失败-头部格式错误", [
            'sign_content' => 'qianmingshibai',
            'authstr' => $authstr,
        ]);
        return false;
    }

    $auth = explode(":", substr($authstr, 5));
    if (count($auth) !== 2 || $auth[0] !== env('QINIU_AK')) {
        /support/Log::debug("签名验证失败-AK不匹配", [
            'sign_content' => 'zhanghuAkshibai',
            'auth_count' => count($auth),
            'auth_ak' => $auth[0],
            'expected_ak' => env('QINIU_AK'),
        ]);
        return false;
    }

    // 获取 URI 和请求体
    $uri = $request->uri();
    if (!empty($_SERVER['QUERY_STRING'])) {
        $uri .= '?' . $_SERVER['QUERY_STRING'];
    }
    $body = file_get_contents('php://input');
    $data = $uri . "/n" . $body;

    // 计算签名
    $computed_sign = $this->URLSafeBase64Encode(hash_hmac('sha1', $data, env('QINIU_SK'), true));

    // 记录调试信息
    /support/Log::debug("签名验证详情", [
        'uri' => $uri,
        'body' => $body,
        'data' => $data,
        'computed_sign' => $computed_sign,
        'received_sign' => $auth[1],
        'secret_key' => substr(env('QINIU_SK'), 0, 4) . '****',
    ]);

    return $computed_sign === $auth[1];
}

public function URLSafeBase64Encode($data): string
{
    return str_replace([' ', '/'], ['-', '_'], base64_encode($data));
}
登录后复制

改进后的代码对URI的处理更加全面,确保了在存在查询字符串的情况下也能正确构建$data。同时,签名计算方法也做了调整,以确保与七牛云的要求完全一致。此外,详细的调试信息记录也帮助开发者更容易找出问题所在。

通过上述改进,开发者成功解决了回调签名验证不一致的问题,确保了与七牛云服务的正常交互。

以上就是为什么七牛云回调签名验证不一致?如何解决?的详细内容,更多请关注php中文网其它相关文章!

https://www.php.cn/faq/1288188.html

发表回复

Your email address will not be published. Required fields are marked *