我正在尝试实现签名的URL,以便短暂访问静态文件。这个想法是:
https://example.com/file.png?download=false&expires=1586852158
)https://example.com/file.png?download=false&expires=1586852158&signature=6635ea14baeeaaffe71333cf6c7fa1f0af9f6cd1a17abb4e75ca275dec5906d1
[当我在服务器上收到请求时,我取出signature
参数,并验证用HMACSHA256签名的URL的其余部分以及相同的私钥是否导致相同的签名。
实现如下:
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的实施是否合理安全?
您正在这里进行哈希处理,而不是数字签名。
哈希就像将纯文本转换为不可逆的代码。常用于密码存储。这不需要密钥,但是需要一些额外的密钥来提高安全性。
[数字签名的意思是,人从密钥中签名文本(私有密钥-只有他可以签名),然后使用他的公共密钥来验证(只有公共密钥可以验证由私有密钥签名的消息)。
据我所知,您需要数字签名,并且可以使用RSA来实现该功能>