Jabber 服务器不回复客户端最终消息

Posted

技术标签:

【中文标题】Jabber 服务器不回复客户端最终消息【英文标题】:Jabber server doesn't reply to Client Final Message 【发布时间】:2014-08-18 06:31:29 【问题描述】:

我正在开发自己的 Jabber 客户端(主要是为了学习 XMPP 和 C#),目前我正在尝试使用基于 TLS 的 SCARAM-SHA-1 连接到服务器。 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) 服务器应该回复 failuresuccess 消息。此外,如果我故意发送错误消息(例如省略客户端证明),它会回复 bad-protocol 消息。服务器是 ejabberd 的默认设置。

我花了几天时间试图找出问题所在,现在有点绝望。我希望这里的人能够帮助我。

(如果需要,我还可以提供我的应用在连接过程中生成的日志)

提前致谢!

【问题讨论】:

【参考方案1】:

我已经测试了agsXMPP SCRAM 的实现,它与 ejabberd 配合得很好。尝试与您的代码进行比较 - https://github.com/meebey/agsxmpp/blob/master/agsxmpp/Sasl/Scram/ScramSha1Mechanism.cs

【讨论】:

以上是关于Jabber 服务器不回复客户端最终消息的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jabber 发送网络消息

用于文件传输的 Jabber 消息

jabber-net 和 vysper 消息广播工具

在不开始聊天的情况下发送 XMPP 消息

如何使用 jabber-net 获取消息历史记录(消息归档)

如何使用 xmpppy 向 jabber 客户端发送消息?