Python 服務端整合 騰訊雲 IM 服務
最近做的專案,需要接入騰訊雲 IM,翻看了一下文件,iOS、Android 以及 Web 端基本上都有 SDK 可以整合。我使用的服務端是用 Python 寫的,騰訊 IM 暫時還沒有 Python 的官方文件。但是在騰訊雲的官方論壇上找到了解決方法。
服務端最基本的一個需求是:使用接入使用者的 identifier 和應用申請的騰訊雲 appid、私鑰等資訊,透過指定演算法,生成使用者用來登入騰訊雲 IM 的 usersig。
原始碼:
#! /usr/bin/python# coding:utf-8import OpenSSL, base64, zlib, json, time ecdsa_pri_key = """ 自己的私鑰 """def list_all_curves(): list = OpenSSL.crypto.get_elliptic_curves() for element in list: print elementdef get_secp256k1(): print OpenSSL.crypto.get_elliptic_curve('secp256k1');def base64_encode_url(data): base64_data = base64.b64encode(data) base64_data = base64_data.replace('+', '*') base64_data = base64_data.replace('/', '-') base64_data = base64_data.replace('=', '_') return base64_datadef base64_decode_url(base64_data): base64_data = base64_data.replace('*', '+') base64_data = base64_data.replace('-', '/') base64_data = base64_data.replace('_', '=') raw_data = base64.b64decode(base64_data) return raw_dataclass TLSSigAPI: """""" __acctype = 0 __identifier = "" __appid3rd = "" __sdkappid = 0 __version = 20151204 __expire = 3600*24*30 # 預設一個月,需要調整請自行修改 __pri_key = "" __pub_key = "" _err_msg = "ok" def __get_pri_key(self): return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, self.__pri_key); def __init__(self, sdkappid, pri_key): self.__sdkappid = sdkappid self.__pri_key = pri_key def __create_dict(self): m = {} m["TLS.account_type"] = "%d" % self.__acctype m["TLS.identifier"] = "%s" % self.__identifier m["TLS.appid_at_3rd"] = "%s" % self.__appid3rd m["TLS.sdk_appid"] = "%d" % self.__sdkappid m["TLS.expire_after"] = "%d" % self.__expire m["TLS.version"] = "%d" % self.__version m["TLS.time"] = "%d" % time.time() return m def __encode_to_fix_str(self, m): fix_str = "TLS.appid_at_3rd:"+m["TLS.appid_at_3rd"]+"n" +"TLS.account_type:"+m["TLS.account_type"]+"n" +"TLS.identifier:"+m["TLS.identifier"]+"n" +"TLS.sdk_appid:"+m["TLS.sdk_appid"]+"n" +"TLS.time:"+m["TLS.time"]+"n" +"TLS.expire_after:"+m["TLS.expire_after"]+"n" return fix_str def tls_gen_sig(self, identifier): self.__identifier = identifier m = self.__create_dict() fix_str = self.__encode_to_fix_str(m) pk_loaded = self.__get_pri_key() sig_field = OpenSSL.crypto.sign(pk_loaded, fix_str, "sha256"); sig_field_base64 = base64.b64encode(sig_field) m["TLS.sig"] = sig_field_base64 json_str = json.dumps(m) sig_cmpressed = zlib.compress(json_str) base64_sig = base64_encode_url(sig_cmpressed) return base64_sig def main(): api = TLSSigAPI(1400001052, ecdsa_pri_key) sig = api.tls_gen_sig("xiaojun") print sigif __name__ == "__main__": main()
過程:
將使用者的資訊組裝成一個字串(json格式的,是直接拼裝的,因為順序不能亂),是哪些資訊,可以看 __encode_to_fix_str;
使用 sha256 將字串 hash,然後再用私鑰簽名,一般加密介面都會一把搞定,加密曲線使用的是 secp256k1;
把第2步得到的緩衝區進行 base64;
將所有使用者的資訊以及第3步得到簽名寫進一個 json 串,此時可以不論順序;
將 json 進行序列化,再 zlib 壓縮,最後 base64(替換了某些字元,具體哪些看程式碼)。
需要注意的是,加密曲線使用的是 secp256k1, 有些系統的 openssl 是不支援這個曲線的。檢視系統所支援的所有曲線,可參考 list_all_curves
, 這個方法會列印出所有支援的曲線。如果你的伺服器恰好支援這個曲線,那經過上面的過程就可以正常使用了。
如果你的伺服器不支援 secp256k1,可以使用 python ecdsa 。
python ecdsa 開發庫
使用 pip 安裝:
pip install ecdsa
由於 python ecdsa 這個開發庫僅支援 ec 格式的私鑰,從騰訊雲下載的私鑰格式是 pk #8 的格式,需要使用 openssl 命令進行轉換。轉換命令如下:
openssl ec -outform PEM -inform PEM -in private.pem -out private_ec.pem
-in 後面的傳入下載的私鑰 -out 後面是轉換後的私鑰檔案
最終實現程式碼:
#! /usr/bin/python# coding:utf-8import OpenSSL, base64, zlib, json, time, hashlib from ecdsa import SigningKey,util# 這裡請填寫應用自己的私鑰ecdsa_pri_key = """ 請填上應用自己的私鑰 """def base64_encode_url(data): base64_data = base64.b64encode(data) base64_data = base64_data.replace('+', '*') base64_data = base64_data.replace('/', '-') base64_data = base64_data.replace('=', '_') return base64_datadef base64_decode_url(base64_data): base64_data = base64_data.replace('*', '+') base64_data = base64_data.replace('-', '/') base64_data = base64_data.replace('_', '=') raw_data = base64.b64decode(base64_data) return raw_dataclass TLSSigAPI: """""" __acctype = 0 __identifier = "" __appid3rd = "" __sdkappid = 0 __version = 20151204 __expire = 3600*24*30 # 預設一個月,需要調整請自行修改 __pri_key = "" __pub_key = "" _err_msg = "ok" def __get_pri_key(self): return self.__pri_key_loaded def __init__(self, sdkappid, pri_key): self.__sdkappid = sdkappid self.__pri_key = pri_key self.__pri_key_loaded = SigningKey.from_pem(self.__pri_key) def __create_dict(self): m = {} m["TLS.account_type"] = "%d" % self.__acctype m["TLS.identifier"] = "%s" % self.__identifier m["TLS.appid_at_3rd"] = "%s" % self.__appid3rd m["TLS.sdk_appid"] = "%d" % self.__sdkappid m["TLS.expire_after"] = "%d" % self.__expire m["TLS.version"] = "%d" % self.__version m["TLS.time"] = "%d" % time.time() return m def __encode_to_fix_str(self, m): fix_str = "TLS.appid_at_3rd:"+m["TLS.appid_at_3rd"]+"n" +"TLS.account_type:"+m["TLS.account_type"]+"n" +"TLS.identifier:"+m["TLS.identifier"]+"n" +"TLS.sdk_appid:"+m["TLS.sdk_appid"]+"n" +"TLS.time:"+m["TLS.time"]+"n" +"TLS.expire_after:"+m["TLS.expire_after"]+"n" return fix_str def tls_gen_sig(self, identifier): self.__identifier = identifier m = self.__create_dict() fix_str = self.__encode_to_fix_str(m) pk_loaded = self.__get_pri_key() sig_field = pk_loaded.sign(fix_str, hashfunc=hashlib.sha256, sigencode=util.sigencode_der) sig_field_base64 = base64.b64encode(sig_field) m["TLS.sig"] = sig_field_base64 json_str = json.dumps(m) sig_cmpressed = zlib.compress(json_str) base64_sig = base64_encode_url(sig_cmpressed) return base64_sig def main(): api = TLSSigAPI(1400001052, ecdsa_pri_key) sig = api.tls_gen_sig("xiaojun") print sigif __name__ == "__main__": main()
參考連結,騰訊雲官方論壇:
作者:莫17
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2618/viewspace-2803050/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 部署小說api服務到騰訊雲API
- EventBridge 整合雲服務實踐
- 服務端指南 服務端概述 | 微服務架構概述服務端微服務架構
- python 搭建 webservice 服務端PythonWeb服務端
- 服務端渲染到前端渲染,再到“服務端渲染”服務端前端
- TCP服務端TCP服務端
- 服務端 unity服務端Unity
- AWS雲服務
- 騰訊雲DDoS防護服務獲Forrester認可,入選全球推薦服務商!REST
- 服務端常見服務安裝及配置服務端
- 客戶端,服務端客戶端服務端
- 服務端,客戶端服務端客戶端
- 使用騰訊雲函式服務執行 laravel 9函式Laravel
- 使用騰訊雲容器服務玩轉 Nginx IngressNginx
- bbossaop遠端服務介紹-遠端服務呼叫例項
- [翻譯]微服務設計模式 - 5. 服務發現 - 服務端服務發現微服務設計模式服務端
- Gateway整合Netty服務GatewayNetty
- 如何在Flutter中整合華為遠端配置服務Flutter
- Java服務端監控:Prometheus與Grafana的整合Java服務端PrometheusGrafana
- FTP服務端部署FTP服務端
- react 服務端渲染React服務端
- 服務端漫遊服務端
- Oracle 服務端程式Oracle服務端
- 如何在 Flutter 中整合華為雲函式服務Flutter函式
- GO 微服務周邊服務持續整合Go微服務
- python建立tcp服務端和客戶端PythonTCP服務端客戶端
- 阿里雲Kubernetes容器服務Istio實踐之整合日誌服務Log Service阿里
- (九)整合spring cloud雲服務架構 - commonservice-config配置服務搭建SpringCloud架構
- 記一次騰訊TBS瀏覽服務整合實踐
- 政府飛上“雲”端:大資料時代的政務服務大資料
- 擁抱雲原生,騰訊釋出TCSS容器安全服務!CSS
- 擁抱雲原生,騰訊釋出TCSS容器安全服務CSS
- 騰訊雲容器服務日誌採集最佳實踐
- 在騰訊雲容器服務 TKE 中實踐 DevOpsdev
- 亞馬遜雲服務(AWS)機器學習服務Amazon SageMaker發力中國亞馬遜機器學習
- 使用多種客戶端消費WCF RestFul服務(一)——服務端客戶端REST服務端
- bbossaop遠端服務介紹-遠端服務id定義規則
- 整合spring cloud雲服務架構 - eureka 基礎SpringCloud架構