我一直关注几篇关于使用WCF的RESTful Web服务的文章,更具体地说,如何在这些文章中进行身份验证。我引用的主要文章是Aaron Skonnard的RESTful Web Services with WCF 3.5。另一个专门处理HMAC身份验证的是基于Skonnards文章的Itai Goldstiens article。
我对两篇文章中引用的“用户密钥”感到困惑。我有一个客户端应用程序,要求用户同时拥有用户名和密码。
在Itai的文章中给出了用于创建Mac的方法
(如下所示),我是对的,认为key
是用户
密码和text
是我们使用的字符串确认
细节其实是正确的吗?
public static string EncodeText(byte[] key, string text, Encoding encoding)
{
HMACMD5 hmacMD5 = new HMACMD5(key);
byte[] textBytes = encoding.GetBytes(text);
byte[] encodedTextBytes =
hmacMD5.ComputeHash(textBytes);
string encodedText =
Convert.ToBase64String(encodedTextBytes);
return encodedText;
}
在我的示例中,text
参数将是请求uri,共享密钥和时间戳(它们将作为请求标头提供并用于防止重放攻击)的组合。
这种形式的身份验证是否合适?我在这里遇到another thread,这表明上面文章中定义的方法是“..(sic)丑陋黑客”。作者没有提出原因,但令人沮丧的是,我花了几个小时阅读这篇文章并让它发挥作用。但是,值得注意的是,在这个问题上接受的答案是关于自定义HMAC授权方案,因此丑陋的黑客引用可能只是它的实现,而不是HMAC算法本身的使用。
下图来自the wikipedia article on Message Authentication Code。我觉得这应该是一种安全的方式,但我只是想确保我理解它的使用是正确的,并确保这不仅仅是一些已经被更好的东西超越的过时机制。
答案 0 :(得分:4)
键可以是用户的密码,但你绝对不应该这样做。
这个密钥至少应该是从用户密码生成的一系列字节 - 通常使用类似PBKDF2的东西 - 但是你还应该包含一些临时的会话理想情况下,攻击者无法知道。
那就是说,很多人可能会告诉你,我太偏执了。
就我个人而言,我知道我不是身份验证方面的专家 - 这是一种非常微妙的平衡行为 - 所以我依靠经过同行评审和验证的技术。例如,SSL(在这种情况下通过客户端证书进行身份验证)可能有它的弱点,但是大多数人都使用它,如果我的一个系统因为SSL弱点而被利用,那么这不是我的错。但是,如果由于某些弱点而发生漏洞利用,我还不够聪明?我将自己踢出前门。
偶然地,对于我的休息服务,我现在使用SCRAM进行身份验证,使用SHA512和512位随机盐进行拉伸操作(很多人会说这是过度的,但我不需要更改它一段时间!),然后使用从身份验证和其他仅服务器已知信息派生的安全令牌(使用HMAC签名并使用AES加密)来保留经过身份验证的会话。令牌是无状态的,就像Asp.Net表单身份验证cookie一样。
密码交换确实非常有效,即使没有SSL(保护密码)也是安全的,并且具有对客户端和服务器进行身份验证的附加优势。会话持久性可以根据站点和客户端进行调整 - 令牌中包含自己的到期时间和绝对到期值,这些可以轻松调整。通过将客户端ID信息加密到该令牌中,可以通过简单地比较来自客户端提供的值的解密值来防止复制到另一台机器上。唯一的问题是关注IP地址信息,是的,它可能是欺骗性的,但主要是你必须考虑漫游网络上的合法用户。