1. 程式人生 > >usersig 生成演算法 python 描述

usersig 生成演算法 python 描述

由於我們的使用者使用的後臺的工具和平臺不盡相同,而我們 api 所能適應的平臺是有限的,所以在此簡要描述下 usersig 的生成演算法,以便在使用者需要而我們又沒有提供時,使用者可以自己進行實現。下面是 python 描述的演算法(其實直接可以用的),

  1. #! /usr/bin/python
  2. # coding:utf-8
  3.  
  4. __author__ = "[email protected]"
  5. __date__ = "$Mar 3, 2016 03:00:43 PM"
  6.  
  7. import OpenSSL
  8. import base64
  9. import zlib
  10. import json
  11. import time
  12.  
  13. ecdsa_pri_key = """
  14. -----BEGIN EC PARAMETERS-----
  15. BgUrgQQACg==
  16. -----END EC PARAMETERS-----
  17. -----BEGIN EC PRIVATE KEY-----
  18. MHQCAQEEIEJDBDY4KVdj3dPBacADreB772ok45A57YWrUUvc5fMQoAcGBSuBBAAK
  19. oUQDQgAEaPVFHhWqRDnKnVlyU5JIzXOUyOJd/pPUwhLUovf+PYBm7otRBptnvJ4E
  20. oJ4qeSJNG0v4XdiqM3mtChkhUEFT3Q==
  21. -----END EC PRIVATE KEY-----
  22. """
  23.  
  24. def list_all_curves():
  25.     list = OpenSSL.crypto.get_elliptic_curves()
  26.     for element in list:
  27.         print element
  28.  
  29. def get_secp256k1():
  30.     print OpenSSL.crypto.get_elliptic_curve('secp256k1');
  31.  
  32.  
  33. def base64_encode_url(data):
  34.     base64_data = base64.b64encode(data)
  35.     base64_data = base64_data.replace('+', '*')
  36.     base64_data = base64_data.replace('/', '-')
  37.     base64_data = base64_data.replace('=', '_')
  38.     return base64_data
  39.  
  40. def base64_decode_url(base64_data):
  41.     base64_data = base64_data.replace('*', '+')
  42.     base64_data = base64_data.replace('-', '/')
  43.     base64_data = base64_data.replace('_', '=')
  44.     raw_data = base64.b64decode(base64_data)
  45.     return raw_data
  46.  
  47. class TLSSigAPI:
  48.     """"""    
  49.     __acctype = 0
  50.     __identifier = ""
  51.     __appid3rd = ""
  52.     __sdkappid = 0
  53.     __version = 20151204
  54.     __expire = 3600*24*30       # 預設一個月,需要調整請自行修改
  55.     __pri_key = ""
  56.     __pub_key = ""
  57.     _err_msg = "ok"
  58.  
  59.     def __get_pri_key(self):
  60.         return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, self.__pri_key);
  61.  
  62.     def __init__(self, sdkappid, pri_key):
  63.         self.__sdkappid = sdkappid
  64.         self.__pri_key = pri_key
  65.  
  66.     def __create_dict(self):
  67.         m = {}
  68.         m["TLS.account_type"] = "%d" % self.__acctype
  69.         m["TLS.identifier"] = "%s" % self.__identifier
  70.         m["TLS.appid_at_3rd"] = "%s" % self.__appid3rd
  71.         m["TLS.sdk_appid"] = "%d" % self.__sdkappid
  72.         m["TLS.expire_after"] = "%d" % self.__expire
  73.         m["TLS.version"] = "%d" % self.__version
  74.         m["TLS.time"] = "%d" % time.time()
  75.         return m
  76.  
  77.     def __encode_to_fix_str(self, m):
  78.         fix_str = "TLS.appid_at_3rd:"+m["TLS.appid_at_3rd"]+"\n" \
  79.                   +"TLS.account_type:"+m["TLS.account_type"]+"\n" \
  80.                   +"TLS.identifier:"+m["TLS.identifier"]+"\n" \
  81.                   +"TLS.sdk_appid:"+m["TLS.sdk_appid"]+"\n" \
  82.                   +"TLS.time:"+m["TLS.time"]+"\n" \
  83.                   +"TLS.expire_after:"+m["TLS.expire_after"]+"\n"
  84.         return fix_str
  85.  
  86.     def tls_gen_sig(self, identifier):
  87.         self.__identifier = identifier
  88.  
  89.         m = self.__create_dict()
  90.         fix_str = self.__encode_to_fix_str(m)
  91.         pk_loaded = self.__get_pri_key()
  92.         sig_field = OpenSSL.crypto.sign(pk_loaded, fix_str, "sha256");
  93.         sig_field_base64 = base64.b64encode(sig_field)
  94.         m["TLS.sig"] = sig_field_base64
  95.         json_str = json.dumps(m)
  96.         sig_cmpressed = zlib.compress(json_str)
  97.         base64_sig = base64_encode_url(sig_cmpressed)
  98.         return base64_sig 
  99.  
  100. def main():
  101.     api = TLSSigAPI(1400001052, ecdsa_pri_key)
  102.     sig = api.tls_gen_sig("xiaojun")
  103.     print sig
  104.  
  105. if __name__ == "__main__":
  106.     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
 

原文網址:http://bbs.qcloud.com/thread-14366-1-1.html