我正在尝试构建以下specification中定义的MDaemon Minger协议UDP请求。假设我正确地解释了规范,对于user@foo.com
的共享密码为U5TttqcKSw0jJcPHrHWb
的邮箱,这个请求的字符串版本应该是什么样的?
user@foo.com d=QTNCMDgxNDEwMUIzRkJDNTM4NTUzQjg1NkU5Rjk2Mjg=
我收到回复,但状态代码始终为“2”,表示请求中传递的凭据无效。服务器未设置为允许匿名查找 - 因此我需要发送凭据。我怀疑我在构建凭证参数的方式上没有做正确的事情。
我相信我正在使用请求正确发送共享密钥凭据,但服务器声明它无效。我不明白我在共享秘密凭证的包装和传输方面做错了什么。我希望对协议规范和我的示例代码有一套新的看法,能够帮助我找到凭证传输问题。
我通过以下代码到达此处:
public bool IsValidUser(string emailAddress)
{
var digestText = _sharedSecret + ":" + emailAddress;
var digest = System.Text.Encoding.ASCII.GetBytes(CreateMD5(digestText));
string query = emailAddress + " d=" + System.Convert.ToBase64String(digest);
var sendBytes = Encoding.ASCII.GetBytes(query);
_udpClient.Send(sendBytes, sendBytes.Length);
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
var results = Encoding.ASCII.GetString(_udpClient.Receive(ref remoteIpEndPoint));
return false;
}
public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
答案 0 :(得分:0)
仔细检查规范和我正在做的事情后,我意识到了我的错误。我不必要地获取哈希值的返回字节数组并将它们转换为十六进制字符串。我没想到我应该(只能)对包含MD5哈希的结果字节数组进行Base64编码。
以下工作代码:
internal bool IsValidUser(string emailAddress)
{
var digestText = _sharedSecret + ":" + emailAddress;
byte[] hashBytes;
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
hashBytes = md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(digestText));
}
var digest = System.Convert.ToBase64String(hashBytes);
string query = emailAddress + " d=" + digest;
var sendBytes = Encoding.ASCII.GetBytes(query);
_udpClient.Send(sendBytes, sendBytes.Length);
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
var results = Encoding.ASCII.GetString(_udpClient.Receive(ref remoteIpEndPoint));
//code which looks at results and return true/false here....
return false;
}