【发布时间】:2020-04-14 08:21:45
【问题描述】:
我正在尝试实现签名 URL 以实现对静态文件的短期访问。 这个想法是:
- 生成带有过期时间戳的 URL(例如
https://example.com/file.png?download=false&expires=1586852158) - 使用 HMACSHA256 和共享密钥对其进行签名,并将签名附加到 URL 的末尾(例如
https://example.com/file.png?download=false&expires=1586852158&signature=6635ea14baeeaaffe71333cf6c7fa1f0af9f6cd1a17abb4e75ca275dec5906d1
当我在服务器上收到请求时,我取出 signature 参数并验证 URL 的其余部分是否使用 HMACSHA256 签名并且相同的共享密钥会产生相同的签名。
实现如下:
public static class URLSigner
{
private static string GetSignatureForUri(string uri, byte[] key)
{
var hmac = new HMACSHA256(key);
var signature = hmac.ComputeHash(Encoding.UTF8.GetBytes(uri));
var hexSignature = BitConverter.ToString(signature).Replace("-", string.Empty).ToLowerInvariant();
return hexSignature;
}
public static string SignUri(string uri, byte[] key)
{
var hexSignature = GetSignatureForUri(uri, key);
return QueryHelpers.AddQueryString(uri, new Dictionary<string, string> { { "signature", hexSignature }});
}
public static bool VerifyUri(string uri, byte[] key)
{
var signatureRegex = "[\\?&]signature=([a-z0-9]+)$";
var signatureMatch = Regex.Match(uri, signatureRegex);
if (!signatureMatch.Success || signatureMatch.Groups.Count != 2)
return false;
var parsedSignature = signatureMatch.Groups[1].Value;
var originalUri = Regex.Replace(uri, signatureRegex, "");
var hexSignature = GetSignatureForUri(originalUri, key);
return hexSignature == parsedSignature;
}
}
它是这样使用的:
var signedUri = URLSigner.SignUri("https://example.com/file.png?download=false", secretKey);
var isVerified = URLSigner.VerifyUri(signedUri, secretKey);
这种签名 URL 的实现是否相当安全?
【问题讨论】:
-
您可能会在codereview.stackexchange.com得到更好的回复
标签: c# security .net-core hmac signing