在C#中生成HMAC SHA1的公钥和私钥

3
我想在Asp.Net MVC 3上实现类似于HMAC-SHA签名算法的REST API服务,类似于AWS。是否有生成用户公钥和密钥的最佳实践?请注意,保留HTML标记,不要提供解释。

你考虑过使用ASP内置的会员功能吗? - CR41G14
是的,我正在实现自己的AuthorizeAttribute,并想知道是否有任何可靠的公钥/密钥对生成解决方案。 - mumu2
1
我建议你在security网站上提出这个问题,我曾经问过一个类似的问题,也许可以帮到你。 - James
你从我的回答中得到足够的信息了吗? - dblood
1个回答

5
我们已经建立了类似的系统。@James提到的问题提供了非常好的信息,请务必阅读。如果可能的话,只在SSL/TLS上部署您的服务。
使用HMAC-SHA签名,您不需要公钥。服务器(服务)和客户端之间有一个共享的秘密密钥用于计算签名。根据上面安全站点上的问题,请确保为每个客户端设置不同的密钥。
对于每个客户端,您还应该具有某种服务客户端ID,该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实现以满足您的需求,并相应地将正确的实现注入到您的代码中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接