我正在使用自己的Jabber客户端(主要是学习XMPP和C#),目前我正尝试使用SCARAM-SHA-1通过TLS连接到服务器。 TLS协商正常以及第一次客户端/服务器消息交换,我获得服务器挑战并使用以下代码生成客户端最终消息:
//Following block generates Client Final Message
//---STEP 1. Creating Salted Password---
byte[] SaltBytes = Encoding.UTF8.GetBytes(Salt);
byte[] SaltedPasswordBytes = GetSaltedPassword(UserPassword, Convert.FromBase64String(Salt), Iterations);
//---STEP 2. Creating Client Key---
byte[] ClientKeyBytes = GetHash("Client Key", SaltedPasswordBytes);
string ClientKey = BitConverter.ToString(ClientKeyBytes);
//---STEP 3. Creating Stored Key---
SHA1 StoredKeySHA = SHA1.Create();
byte[] StoredKeyBytes = StoredKeySHA.ComputeHash(ClientKeyBytes);
string StoredKey = BitConverter.ToString(StoredKeyBytes);
//---STEP 4. Creating Auth Message---
string AuthMessage = "n=test_guy,r=" + ClientNonce + "," + ServerChallenge + "," + "c=" + StringToBase64("n,,") + ",r=" + ClientAndServerNonces; //concern: AuthMessage might start with "n=<username>" or "n,,n=<username>" - which one is right?
LogRTB.Text += "AuthMessage is:\n" + AuthMessage + "\n";
//---STEP 5. Creating Client Signature---
byte[] ClientSignatureBytes = GetHash(AuthMessage, StoredKeyBytes);
string ClientSignature = BitConverter.ToString(ClientSignatureBytes);
//---STEP 6. Creating Client Proof---
LogRTB.Text += "---STEP 6. Calculating Client Proof---\n" + "Client Key is: " + ClientKey + "\nClientSignature is: " + ClientSignature;
byte[] ClientProofBytes = new byte[ClientKeyBytes.Length];
for (int i = 0; i < ClientKeyBytes.Length; ++i)
{
ClientProofBytes[i] = (byte)(ClientKeyBytes[i] ^ ClientSignatureBytes[i]);
}
LogRTB.Text += "\nClient Proof (string) is: " + ClientProof + "\n";
//---STEP 7. Creating Server Key---
byte[] ServerKeyBytes = GetHash("Server Key", SaltedPasswordBytes);
string ServerKey = BitConverter.ToString(ServerKeyBytes);
LogRTB.Text += "Server Key is: " + ServerKey + "\n";
//---STEP 8. Creating Server Signature---
byte[] ServerSignatureBytes = GetHash(AuthMessage, ServerKeyBytes);
string ServerSignature = Convert.ToBase64String(ServerSignatureBytes);
//DONE!
ClientProof = StringToBase64(ClientProof);
string ClientResponse = "c=biws,r=" + ClientAndServerNonces +",p=" + ClientProof; //putting together Client Response (most important part of Client Final Message)
//ClientResponse.Replace("==",""); //NO! just no!
LogRTB.Text += "Client response is:\n" + ClientResponse + "\n"; //DEBUG!
string ClientResponseBase64 = StringToBase64(ClientResponse);
if (IsBase64String(ClientResponseBase64))
{
string ClientFinalMessage = "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + ClientResponseBase64 + "</response>";
LogRTB.Text += "--> Client response (Client Final Message) is:\n" + ClientFinalMessage + "\n";
LogRTB.Text += "--> SENDING NOW!\n";
ServerReply = SendXMPPQueryOverTLS(ServerSocket, SecureConnection, ClientFinalMessage); //Sending Client Final Message
LogRTB.Text += ServerReply;
}
问题是 - 根据RFC6120 (XMPP Core)服务器应该回复失败或成功,我无法从服务器收到任何回复信息。此外,如果我故意发送错误的消息(例如省略客户端证明),它会回复 bad-protocol 消息。服务器使用默认设置进行ejabberd。
我花了几天的时间试图弄清楚什么是错的,现在变得有点绝望了。我希望有人能够帮助我。
(如果需要,我还可以提供我的应用在连接过程中生成的日志)
提前致谢!
答案 0 :(得分:0)
我已经测试了agsXMPP SCRAM实现,它与ejabberd一起运行良好。尝试与您的代码进行比较 - https://github.com/meebey/agsxmpp/blob/master/agsxmpp/Sasl/Scram/ScramSha1Mechanism.cs