当前位置:   article > 正文

C# 生成腾讯云 IM 之 TLSSigAPIv2 UserSig

C# 生成腾讯云 IM 之 TLSSigAPIv2 UserSig

    

目录

关于腾讯 IM 开发 

关于 UserSig

范例运行环境

TLSSigAPIv2 类

设计

实现

小结


关于腾讯 IM 开发 

腾讯微信已经成为当今绝大多数用户必不可少的聊天和通讯工具,腾讯也是国内最早也是最大的即时通信开发商 。腾讯云将高并发、高可靠的即时通信能力以 SDK 和 REST API的形式进行开放,推出即时通信 IM 产品,可以通过简易的方式将腾讯云提供的 IM SDK 集成进自有应用中,配合服务端 REST API 调用,即可轻松拥有微信一样强大的即时通信能力。

关于 UserSig

UserSig 是用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文,采用服务端计算 UserSig,可以最大限度地保障计算 UserSig 所用的密钥信息不被泄露。本文将介绍如何使用 C# 通过 TLSSigAPIv2 类计算 UserSig 的方法。

范例运行环境

操作系统: Windows Server 2019 DataCenter

.net版本: .netFramework4.0 或以上

开发工具:VS2019  C# 

TLSSigAPIv2 类

设计

TLSSigAPIv2 类提供了一系列方法,用于生成UserSig,其关键属性方法说明如下:

序号类型说明
1private readonly int sdkappid属性

sdk开发者id,如何获取请参照如下链接:

腾讯IM即时通信控制台

2private readonly string key属性sdk开发者key ,如何获取请参照如下链接:

腾讯IM即时通信控制台

3private string HMACSHA256(string identifier, long currTime, int expire, string base64UserBuf, bool userBufEnabled)方法HMAC-SHA256 算法方法。即时通信 IM 服务自2019.07.19开始启用新的签名算法,从之前的 ECDSA-SHA256 升级为 HMAC-SHA256。 2019.07.19以后创建的 SDKAppID 均会采用新的 HMAC-SHA256 算法。
4public string GenSig(string identifier, int expire = 180 * 86400)方法

生成UserSig方法。

参数:Identifier为用户 ID;

参数:expire为有效期,单位为秒。建议 UserSig 有效期最短不小于24小时,最长不超过50年。为了您的账号安全,建议将 UserSig 有效期设置为两个月。

实现

实现代码如下:

  1. public class TLSSigAPIv2
  2. {
  3. private readonly int sdkappid;
  4. private readonly string key;
  5. public TLSSigAPIv2(int sdkappid, string key)
  6. {
  7. this.sdkappid = sdkappid;
  8. this.key = key;
  9. }
  10. public byte[] GetUserBuf(string account, uint authId, uint expireTime, uint privilegeBitMap, uint accountType)
  11. {
  12. int length = 1 + 2 + account.Length + 20;
  13. int offset = 0;
  14. byte[] userBuf = new byte[length];
  15. userBuf[offset++] = 0;
  16. userBuf[offset++] = (byte)((account.Length & 0xFF00) >> 8);
  17. userBuf[offset++] = (byte)(account.Length & 0x00FF);
  18. byte[] accountByte = System.Text.Encoding.UTF8.GetBytes(account);
  19. accountByte.CopyTo(userBuf, offset);
  20. offset += account.Length;
  21. userBuf[offset++] = (byte)((sdkappid & 0xFF000000) >> 24);
  22. userBuf[offset++] = (byte)((sdkappid & 0x00FF0000) >> 16);
  23. userBuf[offset++] = (byte)((sdkappid & 0x0000FF00) >> 8);
  24. userBuf[offset++] = (byte)(sdkappid & 0x000000FF);
  25. userBuf[offset++] = (byte)((authId & 0xFF000000) >> 24);
  26. userBuf[offset++] = (byte)((authId & 0x00FF0000) >> 16);
  27. userBuf[offset++] = (byte)((authId & 0x0000FF00) >> 8);
  28. userBuf[offset++] = (byte)(authId & 0x000000FF);
  29. userBuf[offset++] = (byte)((expireTime & 0xFF000000) >> 24);
  30. userBuf[offset++] = (byte)((expireTime & 0x00FF0000) >> 16);
  31. userBuf[offset++] = (byte)((expireTime & 0x0000FF00) >> 8);
  32. userBuf[offset++] = (byte)(expireTime & 0x000000FF);
  33. userBuf[offset++] = (byte)((privilegeBitMap & 0xFF000000) >> 24);
  34. userBuf[offset++] = (byte)((privilegeBitMap & 0x00FF0000) >> 16);
  35. userBuf[offset++] = (byte)((privilegeBitMap & 0x0000FF00) >> 8);
  36. userBuf[offset++] = (byte)(privilegeBitMap & 0x000000FF);
  37. userBuf[offset++] = (byte)((accountType & 0xFF000000) >> 24);
  38. userBuf[offset++] = (byte)((accountType & 0x00FF0000) >> 16);
  39. userBuf[offset++] = (byte)((accountType & 0x0000FF00) >> 8);
  40. userBuf[offset++] = (byte)(accountType & 0x000000FF);
  41. return userBuf;
  42. }
  43. private static byte[] CompressBytes(byte[] sourceByte)
  44. {
  45. MemoryStream inputStream = new MemoryStream(sourceByte);
  46. Stream outStream = CompressStream(inputStream);
  47. byte[] outPutByteArray = new byte[outStream.Length];
  48. outStream.Position = 0;
  49. outStream.Read(outPutByteArray, 0, outPutByteArray.Length);
  50. return outPutByteArray;
  51. }
  52. private static Stream CompressStream(Stream sourceStream)
  53. {
  54. MemoryStream streamOut = new MemoryStream();
  55. ZOutputStream streamZOut = new ZOutputStream(streamOut, zlibConst.Z_DEFAULT_COMPRESSION);
  56. CopyStream(sourceStream, streamZOut);
  57. streamZOut.finish();
  58. return streamOut;
  59. }
  60. public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
  61. {
  62. byte[] buffer = new byte[2000];
  63. int len;
  64. while ((len = input.Read(buffer, 0, 2000)) > 0)
  65. {
  66. output.Write(buffer, 0, len);
  67. }
  68. output.Flush();
  69. }
  70. private string HMACSHA256(string identifier, long currTime, int expire, string base64UserBuf, bool userBufEnabled)
  71. {
  72. string rawContentToBeSigned = "TLS.identifier:" + identifier + "\n"
  73. + "TLS.sdkappid:" + sdkappid + "\n"
  74. + "TLS.time:" + currTime + "\n"
  75. + "TLS.expire:" + expire + "\n";
  76. if (true == userBufEnabled)
  77. {
  78. rawContentToBeSigned += "TLS.userbuf:" + base64UserBuf + "\n";
  79. }
  80. using (HMACSHA256 hmac = new HMACSHA256())
  81. {
  82. UTF8Encoding encoding = new UTF8Encoding();
  83. Byte[] textBytes = encoding.GetBytes(rawContentToBeSigned);
  84. Byte[] keyBytes = encoding.GetBytes(key);
  85. Byte[] hashBytes;
  86. using (HMACSHA256 hash = new HMACSHA256(keyBytes))
  87. hashBytes = hash.ComputeHash(textBytes);
  88. return Convert.ToBase64String(hashBytes);
  89. }
  90. }
  91. private string GenSig(string identifier, int expire, byte[] userbuf, bool userBufEnabled)
  92. {
  93. DateTime epoch = new DateTime(1970, 1, 1); // unix 时间戳
  94. Int64 currTime = (Int64)(DateTime.UtcNow - epoch).TotalMilliseconds / 1000;
  95. string base64UserBuf;
  96. string jsonData;
  97. if (true == userBufEnabled)
  98. {
  99. base64UserBuf = Convert.ToBase64String(userbuf);
  100. string base64sig = HMACSHA256(identifier, currTime, expire, base64UserBuf, userBufEnabled);
  101. // 没有引入 json 库,所以这里手动进行组装,
  102. // 这里如果用户 identifier 中出现 json 元字符将会出错
  103. jsonData = String.Format("{{"
  104. + "\"TLS.ver\":" + "\"2.0\","
  105. + "\"TLS.identifier\":" + "\"{0}\","
  106. + "\"TLS.sdkappid\":" + "{1},"
  107. + "\"TLS.expire\":" + "{2},"
  108. + "\"TLS.time\":" + "{3},"
  109. + "\"TLS.sig\":" + "\"{4}\","
  110. + "\"TLS.userbuf\":" + "\"{5}\""
  111. + "}}", identifier, sdkappid, expire, currTime, base64sig, base64UserBuf);
  112. }
  113. else
  114. {
  115. // 没有引入 json 库,所以这里手动进行组装
  116. string base64sig = HMACSHA256(identifier, currTime, expire, "", false);
  117. jsonData = String.Format("{{"
  118. + "\"TLS.ver\":" + "\"2.0\","
  119. + "\"TLS.identifier\":" + "\"{0}\","
  120. + "\"TLS.sdkappid\":" + "{1},"
  121. + "\"TLS.expire\":" + "{2},"
  122. + "\"TLS.time\":" + "{3},"
  123. + "\"TLS.sig\":" + "\"{4}\""
  124. + "}}", identifier, sdkappid, expire, currTime, base64sig);
  125. }
  126. byte[] buffer = Encoding.UTF8.GetBytes(jsonData);
  127. return Convert.ToBase64String(CompressBytes(buffer))
  128. .Replace('+', '*').Replace('/', '-').Replace('=', '_');
  129. }
  130. public string GenSig(string identifier, int expire = 180 * 86400)
  131. {
  132. return GenSig(identifier, expire, null, false);
  133. }
  134. public string GenSigWithUserBuf(string identifier, int expire, byte[] userBuf)
  135. {
  136. return GenSig(identifier, expire, userBuf, true);
  137. }
  138. }

小结

服务端的调用引用代码如下:

  1. string SDKAppId="申请的SDKAppID";
  2. string SDKAppIdSecret="申请的SDKAppIdSecret";
  3. string AppAdminId="IM平台超级管理员UserID";
  4. TLSSigAPIv2 sig = new TLSSigAPIv2(int.Parse(SDKAppId),SDKAppIdSecret);
  5. string _sig = sig.GenSig(AppAdminId);

后续我们将介绍如何通过UserSig 来实现 IM 服务端 REST API,REST API 是即时通信 IM 提供给 App 后台的 HTTP 管理接口,是一组原始的且管理功能强大的API。

本文代码仅供您参考使用,感谢您的阅读,希望本文能够对您有所帮助。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/613079
推荐阅读
相关标签
  

闽ICP备14008679号