usersig 生成演算法 python 描述
阿新 • • 發佈:2018-11-12
由於我們的使用者使用的後臺的工具和平臺不盡相同,而我們 api 所能適應的平臺是有限的,所以在此簡要描述下 usersig 的生成演算法,以便在使用者需要而我們又沒有提供時,使用者可以自己進行實現。下面是 python 描述的演算法(其實直接可以用的),
- #! /usr/bin/python
- # coding:utf-8
- __author__ = "[email protected]"
- __date__ = "$Mar 3, 2016 03:00:43 PM"
- import OpenSSL
- import base64
- import zlib
- import json
- import time
- ecdsa_pri_key = """
- -----BEGIN EC PARAMETERS-----
- BgUrgQQACg==
- -----END EC PARAMETERS-----
- -----BEGIN EC PRIVATE KEY-----
- MHQCAQEEIEJDBDY4KVdj3dPBacADreB772ok45A57YWrUUvc5fMQoAcGBSuBBAAK
- oUQDQgAEaPVFHhWqRDnKnVlyU5JIzXOUyOJd/pPUwhLUovf+PYBm7otRBptnvJ4E
- oJ4qeSJNG0v4XdiqM3mtChkhUEFT3Q==
- -----END EC PRIVATE KEY-----
- """
- def list_all_curves():
- list = OpenSSL.crypto.get_elliptic_curves()
- for element in list:
- print element
- def 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_data
- def 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_data
- class 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 sig
- if __name__ == "__main__":
- main()
複製程式碼
下面用文字簡要描述下,
1.將使用者的資訊組裝成一個字串(json格式的,是直接拼裝的,因為順序不能亂),是哪些資訊,可以看 __encode_to_fix_str;
2.使用 sha256 將字串 hash,然後再用私鑰簽名,一般加密介面都會一把搞定,加密曲線使用的是 secp256k1;
3.把第2步得到的緩衝區進行base64;
4.將所有使用者的資訊以及第3步得到簽名寫進一個 json 串,此時可以不論順序;
5.將 json 進行序列化,再 zlib 壓縮,最後 base64(替換了某些字元,具體哪些看程式碼),出爐。
特別注意,這段程式碼在 windows 上驗證沒問題,但是紅帽系(rel 和 centos)上不支援我們使用的曲線,list_all_curves 可以列印所有支援的曲線,紅帽系的沒有 secp256k1。
如果發現系統所帶的 openssl 擴充套件不支援我們選定的曲線,可以參考 http://bbs.qcloud.com/thread-23280-1-1.html。