本文目录导读:

在 PHP 中生成签名 URL(通常用于实现 URL 防盗链、API 鉴权或 CDN 认证),常见的方法有两大类:
- 简单的对称加密签名(如 md5/timestamp 组合)
- 基于密钥的哈希签名(如 HMAC-SHA1)
- 阿里云/腾讯云等云服务商的 A/B 鉴权签名
下面给出这几种常见场景的 PHP 实现代码。
简单防盗链签名(MD5 + 时间戳)
常用于保护静态资源(如图片、视频),防止直接访问。
function signUrl(string $baseUrl, string $secretKey, int $expireTime = 3600): string
{
// 1. 生成过期时间戳
$expiration = time() + $expireTime;
// 2. 拼接待签名字符串(可加入路径、IP限制等)
$stringToSign = $baseUrl . '-' . $expiration . '-' . $secretKey;
// 3. 计算签名
$signature = md5($stringToSign);
// 4. 拼接签名参数
$signedUrl = $baseUrl . '?sign=' . $signature . '&expire=' . $expiration;
return $signedUrl;
}
// 使用示例
$url = 'http://example.com/files/video.mp4';
$key = 'MySecretKey123';
$signedUrl = signUrl($url, $key, 1800); // 30分钟有效
echo $signedUrl;
验证端(服务端):
function verifySignedUrl(string $url, string $secretKey): bool
{
$parsed = parse_url($url);
parse_str($parsed['query'] ?? '', $query);
$sign = $query['sign'] ?? '';
$expire = $query['expire'] ?? 0;
// 1. 过期判断
if (time() > $expire) return false;
// 2. 重新计算签名
$basePath = $parsed['scheme'] . '://' . $parsed['host'] . $parsed['path'];
$stringToSign = $basePath . '-' . $expire . '-' . $secretKey;
$expectedSign = md5($stringToSign);
// 3. 比较签名(防止时序攻击)
return hash_equals($expectedSign, $sign);
}
HMAC-SHA1 签名(更安全,常见于 API)
HMAC 配合 SHA1/SHA256 更安全,常用于 OAuth 或云 API 签名。
function signUrlHmac(string $uri, array $params, string $secretKey): string
{
// 1. 按参数名排序
ksort($params);
// 2. 拼接查询字符串
$queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
// 3. 构建待签字符串(通常包含 HTTP 方法+路径+查询字符串)
$stringToSign = "GET\n{$uri}\n{$queryString}";
// 4. 计算 HMAC-SHA1 并 base64 编码
$signature = base64_encode(
hash_hmac('sha1', $stringToSign, $secretKey, true)
);
// 5. 将签名加入参数
$params['signature'] = $signature;
return $uri . '?' . http_build_query($params);
}
// 使用示例
$baseUri = '/api/v1/users';
$params = [
'uid' => 123,
'timestamp' => time(),
];
$secret = 'my-hmac-key';
$signedUrl = signUrlHmac($baseUri, $params, $secret);
echo "http://api.example.com" . $signedUrl;
阿里云 CDN URL 鉴权(A/B/C/D 类)
以阿里云 CDN 鉴权方式 C(最常见)为例:
原理
签名串 = md5(key + uri + expire_timestamp)
URL = http://domain/path?auth_key=expire-uid-rand-md5
PHP 实现
function aliyunCdnSign(string $path, string $key, int $expireTime, string $uid = '0', string $rand = ''): string
{
$timestamp = time() + $expireTime;
$rand = $rand ?: random_int(100000, 999999);
// 拼接待签字符串: key + path + timestamp
$stringToSign = $key . $path . $timestamp;
$md5 = md5($stringToSign);
// 生成 auth_key 参数
$authKey = "{$timestamp}-{$uid}-{$rand}-{$md5}";
return $path . '?auth_key=' . $authKey;
}
// 使用示例
$path = '/files/1.jpg';
$key = 'aliyun_cdn_secret';
$url = aliyunCdnSign($path, $key, 3600);
echo "http://cdn.example.com{$url}";
验证端(CDN 边缘节点自动验证,或你也可以自己写):
function verifyAliyunCdn(string $fullUrl, string $key): bool
{
$parts = parse_url($fullUrl);
parse_str($parts['query'] ?? '', $query);
$authKey = $query['auth_key'] ?? '';
$segments = explode('-', $authKey);
if (count($segments) !== 4) return false;
[$expire, $uid, $rand, $sign] = $segments;
// 过期判断
if (time() > intval($expire)) return false;
// 重新计算签名
$reSign = md5($key . $parts['path'] . $expire);
return hash_equals($reSign, $sign);
}
腾讯云 CDN URL 鉴权(时间戳防盗链)
腾讯云常用的 t=(时间戳) + key= 方式:
function tencentCdnSign(string $path, string $key, int $expireTime): string
{
// 1. 生成过期 Unix 时间戳(十进制)
$expire = time() + $expireTime;
// 2. 拼接待签字符串: path + key + t
$stringToSign = $path . $key . $expire;
// 3. 计算 md5
$sign = md5($stringToSign);
// 4. 拼接到 URL
return $path . "?t={$expire}&key={$sign}";
}
// 使用示例
echo tencentCdnSign('/resource/1.mp4', 'my_key', 1800);
总结建议
| 场景 | 推荐签名方式 | 关键点 |
|---|---|---|
| 简单 URL 防盗链 | MD5 + timestamp | 容易实现,但安全性一般 |
| 高安全 API/文件 | HMAC-SHA1/SHA256 | 防篡改,防重放 |
| 阿里云 CDN | 方式 C(auth_key) | 注意待签字符串顺序 |
| 腾讯云 CDN | key + t 模式 | 注意 t 是十进制时间戳 |
重要:
- 所有签名密钥应妥善保存(环境变量或配置文件,不出现在代码中)。
- 建议使用
hash_equals()比较签名,防止时序攻击。- 时间戳验证时注意时区(统一使用 UTC/Unix 时间戳)。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播