3

我想在 Asp.Net MVC 3 上为 REST API 服务实现类似 HMAC-SHA 签名算法的AWS。是否有任何最佳实践来生成用户的公钥和秘密?

4

1 回答 1

5

我们已经建立了一个类似的系统。@James 引用的问题提供了非常好的信息。请务必阅读。如果可能,仅通过 SSL/TLS 部署您的服务。

使用 HMAC-SHA 签名,您不需要公钥。服务器(服务)和客户端共享一个密钥,用于计算签名。根据上面提到的安全站点上的问题,确保每个客户端都有不同的密钥。

对于每个客户端,您还应该具有某种不同于您必须识别客户端的任何其他 ID 的服务客户端 ID。此服务客户端 ID 在请求标头中发送,因此您可以识别客户端。识别客户端后,您可以获得有关客户端的所需信息,包括客户端的服务密钥。

除了服务客户端 ID 之外,请求标头还应包含生成的实际签名。我还建议在标题中包含时间戳(更多内容见下文)。因此,您的请求将具有类似于以下的标头:

MySvc-Clientid: ServiceId
MySvc-Signature: Signature
MySvc-Timestamp: TimeStamp

要使用 .NET/C# 生成客户端密钥,您可以创建一个生成 Rijndael 密钥的字符串表示形式的方法,该密钥可以传递给客户端。这是一个例子。

    public string CreateServiceClientKey()
    {
        SymmetricAlgorithm symAlg = SymmetricAlgorithm.Create("Rijndael");

        symAlg.KeySize = 128;

        byte[] key = symAlg.Key;

        StringBuilder sb = new StringBuilder(key.Length * 2);

        foreach (byte b in key)
        {
            sb.AppendFormat("{0:x2}", b);
        }

        return sb.ToString();
    }

在我们的系统中,当启用新的服务客户端时,会生成服务客户端 id 和服务密钥并将其存储在客户端的数据库中。服务客户端 ID 可能只是一个 GUID。

客户端的服务密钥是您和客户端之间的共享密钥。仅通过安全机制将其交付给客户端,例如在 SSL/TLS 上运行的网站的经过身份验证的部分。否则,您将向其他人敞开心扉,让他人获得密钥。

时间戳应由客户端生成,并包含在生成签名的签名字符串中。这为签名增加了时间特定的可变性。AWS 也这样做。

关于要签名的字符串,在您这边,我还建议您定义一个接口,以便在与请求签名进行比较时构建您要签名的字符串。这将允许您为不同的服务甚至不同的操作构建不同的实现。这对我们的实施非常有用。这是一个例子:

public interface IStringToSignBuilder
{
    string Build(ServiceSignatureDetails details);
}

/// <summary>
/// Class is a data entity that defines the specific details
/// required for a Service Signature
/// </summary>
public class ServiceSignatureDetails
{
    public string HttpMethod { get; set; }
    public string ServiceClientId { get; set; }
    public string ServiceClientKey { get; set; }
    public string UriAbsolutePath { get; set; }
    public string DomainName { get; set; }
    public string CompanyName { get; set; }
    public string DateTimeStamp { get; set; }
    public string Data { get; set; }
}

然后,您可以构建IStringToSignBuilder满足您需求的特定实现,并相应地将正确的实现注入您的代码中。

于 2012-12-13T16:32:14.443 回答