|
1 | | -#! /usr/bin/python |
2 | | -# coding:utf-8 |
3 | | - |
4 | | -# 此文件是 tls sig api 的 python 另一种实现 |
5 | | -# 使用了 python ecdsa 开发库 |
6 | | - |
7 | | -__author__ = "tls@tencent.com" |
8 | | -__date__ = "$Oct 2, 2016 11:17:43 PM" |
9 | | - |
10 | | -import base64 |
11 | | -import zlib |
12 | | -import json |
13 | | -import time |
14 | | - |
15 | | -# python ecdsa 开发库请到 https://github.com/warner/python-ecdsa |
16 | | -# 或者 tls 技术支持分享的链接 http://share.weiyun.com/24b674bced4f84ecbbe6a7945738b9f4 |
17 | | -# 下载,下载完毕之后进入其根目录,运行下面的命令进行安装, |
18 | | -# python setup.py install |
19 | | -# ubuntu 用户可能需要添加 sudo |
20 | | -# 由于 python ecdsa 这个开发库仅支持 ec 格式的私钥,从腾讯云下载的私钥格式是 |
21 | | -# pk #8 的格式,需要使用 openssl 命令进行转换,或者使用我们工具包中的 openssl 进行转换 |
22 | | -# 下面是转换命令 |
23 | | -# openssl ec -outform PEM -inform PEM -in private.pem -out private_ec.pem |
24 | | -# -in 后面的传入下载的私钥 -out 后面是转换后的私钥文件 |
25 | | - |
26 | | -from ecdsa import SigningKey,util |
27 | | -import hashlib |
28 | | - |
29 | | -# 这里请填写应用自己的私钥 |
30 | | -ecdsa_pri_key = """ |
31 | | ------BEGIN EC PRIVATE KEY----- |
32 | | -MHQCAQEEIEJDBDY4KVdj3dPBacADreB772ok45A57YWrUUvc5fMQoAcGBSuBBAAK |
33 | | -oUQDQgAEaPVFHhWqRDnKnVlyU5JIzXOUyOJd/pPUwhLUovf+PYBm7otRBptnvJ4E |
34 | | -oJ4qeSJNG0v4XdiqM3mtChkhUEFT3Q== |
35 | | ------END EC PRIVATE KEY----- |
36 | | -""" |
37 | | - |
38 | | -def base64_encode_url(data): |
39 | | - base64_data = base64.b64encode(data) |
40 | | - base64_data = base64_data.replace('+', '*') |
41 | | - base64_data = base64_data.replace('/', '-') |
42 | | - base64_data = base64_data.replace('=', '_') |
43 | | - return base64_data |
44 | | - |
45 | | -def base64_decode_url(base64_data): |
46 | | - base64_data = base64_data.replace('*', '+') |
47 | | - base64_data = base64_data.replace('-', '/') |
48 | | - base64_data = base64_data.replace('_', '=') |
49 | | - raw_data = base64.b64decode(base64_data) |
50 | | - return raw_data |
51 | | - |
52 | | -class TLSSigAPI: |
53 | | - """""" |
54 | | - __acctype = 0 |
55 | | - __identifier = "" |
56 | | - __appid3rd = "" |
57 | | - __sdkappid = 0 |
58 | | - __version = 20151204 |
59 | | - __expire = 3600*24*30 # 默认一个月,需要调整请自行修改 |
60 | | - __pri_key = "" |
61 | | - __pub_key = "" |
62 | | - _err_msg = "ok" |
63 | | - |
64 | | - |
65 | | - def __get_pri_key(self): |
66 | | - return self.__pri_key_loaded |
67 | | - |
68 | | - def __init__(self, sdkappid, pri_key): |
69 | | - self.__sdkappid = sdkappid |
70 | | - self.__pri_key = pri_key |
71 | | - self.__pri_key_loaded = SigningKey.from_pem(self.__pri_key) |
72 | | - |
73 | | - def __create_dict(self): |
74 | | - m = {} |
75 | | - m["TLS.account_type"] = "%d" % self.__acctype |
76 | | - m["TLS.identifier"] = "%s" % self.__identifier |
77 | | - m["TLS.appid_at_3rd"] = "%s" % self.__appid3rd |
78 | | - m["TLS.sdk_appid"] = "%d" % self.__sdkappid |
79 | | - m["TLS.expire_after"] = "%d" % self.__expire |
80 | | - m["TLS.version"] = "%d" % self.__version |
81 | | - m["TLS.time"] = "%d" % time.time() |
82 | | - return m |
83 | | - |
84 | | - def __encode_to_fix_str(self, m): |
85 | | - fix_str = "TLS.appid_at_3rd:"+m["TLS.appid_at_3rd"]+"\n" \ |
86 | | - +"TLS.account_type:"+m["TLS.account_type"]+"\n" \ |
87 | | - +"TLS.identifier:"+m["TLS.identifier"]+"\n" \ |
88 | | - +"TLS.sdk_appid:"+m["TLS.sdk_appid"]+"\n" \ |
89 | | - +"TLS.time:"+m["TLS.time"]+"\n" \ |
90 | | - +"TLS.expire_after:"+m["TLS.expire_after"]+"\n" |
91 | | - return fix_str |
92 | | - |
93 | | - def tls_gen_sig(self, identifier): |
94 | | - self.__identifier = identifier |
95 | | - m = self.__create_dict() |
96 | | - fix_str = self.__encode_to_fix_str(m) |
97 | | - pk_loaded = self.__get_pri_key() |
98 | | - sig_field = pk_loaded.sign(fix_str, hashfunc=hashlib.sha256, sigencode=util.sigencode_der) |
99 | | - sig_field_base64 = base64.b64encode(sig_field) |
100 | | - m["TLS.sig"] = sig_field_base64 |
101 | | - json_str = json.dumps(m) |
102 | | - sig_cmpressed = zlib.compress(json_str) |
103 | | - base64_sig = base64_encode_url(sig_cmpressed) |
104 | | - return base64_sig |
105 | | - |
106 | | -def main(): |
107 | | - api = TLSSigAPI(1400001052, ecdsa_pri_key) |
108 | | - sig = api.tls_gen_sig("xiaojun") |
109 | | - print sig |
110 | | - |
111 | | -if __name__ == "__main__": |
112 | | - main() |
| 1 | +#! /usr/bin/python |
| 2 | +# coding:utf-8 |
| 3 | + |
| 4 | +import OpenSSL |
| 5 | +import base64 |
| 6 | +import zlib |
| 7 | +import json |
| 8 | +import time |
| 9 | + |
| 10 | +ecdsa_pri_key = """ |
| 11 | +-----BEGIN PRIVATE KEY----- |
| 12 | +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgK55Mnxa+AH7tvzvAyfxW |
| 13 | +aN1rZdL0Xv2hyg3k2eqjeHyhRANCAAQvkz6T2Or8EEzgF0lWBF0RtrxjJYUF6RqM |
| 14 | +2JUDAP4UD/cIwhGTYlWC2ZRPZEvaXZJapz2Y2c2TwcgW13sAnIKZ |
| 15 | +-----END PRIVATE KEY----- |
| 16 | +""" |
| 17 | + |
| 18 | +ecdsa_pub_key = """ |
| 19 | +-----BEGIN PUBLIC KEY----- |
| 20 | +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEL5M+k9jq/BBM4BdJVgRdEba8YyWFBeka |
| 21 | +jNiVAwD+FA/3CMIRk2JVgtmUT2RL2l2SWqc9mNnNk8HIFtd7AJyCmQ== |
| 22 | +-----END PUBLIC KEY----- |
| 23 | +""" |
| 24 | + |
| 25 | +def list_all_curves(): |
| 26 | + list = OpenSSL.crypto.get_elliptic_curves() |
| 27 | + for element in list: |
| 28 | + print(element) |
| 29 | + |
| 30 | + |
| 31 | +def get_prime256v1(): |
| 32 | + print(OpenSSL.crypto.get_elliptic_curve('prime256v1')) |
| 33 | + |
| 34 | + |
| 35 | +def base64_encode_url(data): |
| 36 | + base64_data = base64.b64encode(data) |
| 37 | + base64_data = base64_data.replace('+', '*') |
| 38 | + base64_data = base64_data.replace('/', '-') |
| 39 | + base64_data = base64_data.replace('=', '_') |
| 40 | + return base64_data |
| 41 | + |
| 42 | +def base64_decode_url(base64_data): |
| 43 | + base64_data = base64_data.replace('*', '+') |
| 44 | + base64_data = base64_data.replace('-', '/') |
| 45 | + base64_data = base64_data.replace('_', '=') |
| 46 | + raw_data = base64.b64decode(base64_data) |
| 47 | + return raw_data |
| 48 | + |
| 49 | +class TLSSigAPI: |
| 50 | + """""" |
| 51 | + |
| 52 | + __acctype = 0 |
| 53 | + __identifier = "" |
| 54 | + __appid3rd = "" |
| 55 | + __sdkappid = 0 |
| 56 | + __version = 20151204 |
| 57 | + __expire = 3600*24*180 |
| 58 | + __pri_key = "" |
| 59 | + __pub_key = "" |
| 60 | + _err_msg = "ok" |
| 61 | + |
| 62 | + def __get_pri_key(self): |
| 63 | + return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, self.__pri_key); |
| 64 | + |
| 65 | + def __get_pub_key(self): |
| 66 | + print(self.__pub_key) |
| 67 | + return OpenSSL.crypto.load_publickey(OpenSSL.crypto.FILETYPE_PEM, self.__pub_key); |
| 68 | + |
| 69 | + def __init__(self, sdkappid, pri_key, pub_key): |
| 70 | + self.__sdkappid = sdkappid |
| 71 | + self.__pri_key = pri_key |
| 72 | + self.__pub_key = pub_key |
| 73 | + |
| 74 | + def __create_dict(self): |
| 75 | + m = {} |
| 76 | + m["TLS.account_type"] = "%d" % self.__acctype |
| 77 | + m["TLS.identifier"] = "%s" % self.__identifier |
| 78 | + m["TLS.appid_at_3rd"] = "%s" % self.__appid3rd |
| 79 | + m["TLS.sdk_appid"] = "%d" % self.__sdkappid |
| 80 | + m["TLS.expire_after"] = "%d" % self.__expire |
| 81 | + m["TLS.version"] = "%d" % self.__version |
| 82 | + m["TLS.time"] = "%d" % time.time() |
| 83 | + return m |
| 84 | + |
| 85 | + def __encode_to_fix_str(self, m): |
| 86 | + fix_str = "TLS.appid_at_3rd:"+m["TLS.appid_at_3rd"]+"\n" \ |
| 87 | + +"TLS.account_type:"+m["TLS.account_type"]+"\n" \ |
| 88 | + +"TLS.identifier:"+m["TLS.identifier"]+"\n" \ |
| 89 | + +"TLS.sdk_appid:"+m["TLS.sdk_appid"]+"\n" \ |
| 90 | + +"TLS.time:"+m["TLS.time"]+"\n" \ |
| 91 | + +"TLS.expire_after:"+m["TLS.expire_after"]+"\n" |
| 92 | + return fix_str |
| 93 | + |
| 94 | + def __check_field(self, m): |
| 95 | + if m["TLS.identifier"] != self.__identifier: |
| 96 | + self._err_msg = "identifier %s in req and identifier %s in tlssig not match" % (self.__identifier, m["TLS.identifier"]) |
| 97 | + return -1 |
| 98 | + if atoi(m["TLS.sdk_appid"]) != self.__sdkappid: |
| 99 | + self._err_msg = "sdkappid %d in req and identifier %s in tlssig not match" % (self.__identifier, m["TLS.sdk_appid"]) |
| 100 | + return -2 |
| 101 | + current_time = time.time() |
| 102 | + if atoi(m["TLS.expire_after"])+atoi(m["TLS.time"]) < current_time: |
| 103 | + self._err_msg = "tls sig expired expire %s add init time %s lower than current time %d" % (m["TLS.expire_after"], m["TLS.time"], current_time) |
| 104 | + return -3, |
| 105 | + return atoi(m["TLS.expire_after"]), atoi(m["TLS.time"]) |
| 106 | + |
| 107 | + def tls_gen_sig(self, identifier): |
| 108 | + self.__identifier = identifier |
| 109 | + |
| 110 | + m = self.__create_dict() |
| 111 | + fix_str = self.__encode_to_fix_str(m) |
| 112 | + pk_loaded = self.__get_pri_key() |
| 113 | + sig_field = OpenSSL.crypto.sign(pk_loaded, fix_str, "sha256"); |
| 114 | + sig_field_base64 = base64.b64encode(sig_field) |
| 115 | + m["TLS.sig"] = sig_field_base64 |
| 116 | + json_str = json.dumps(m) |
| 117 | + sig_cmpressed = zlib.compress(json_str) |
| 118 | + base64_sig = base64_encode_url(sig_cmpressed) |
| 119 | + return base64_sig |
| 120 | + |
| 121 | + def gen_sig(self, identifier, expire=3600*24*180): |
| 122 | + self.__expire = expire |
| 123 | + return self.tls_gen_sig(identifier) |
| 124 | + |
| 125 | + def tls_verify_sig(self, tlssig, identifier): |
| 126 | + self.__identifier = identifier |
| 127 | + |
| 128 | + sig_cmpressed = base64_decode_url(tlssig) |
| 129 | + json_str = zlib.decompress(sig_cmpressed) |
| 130 | + m = json.loads(json_str) |
| 131 | + fix_str = self.__encode_to_fix_str(m) |
| 132 | + pubkey_loaded = self.__get_pub_key() |
| 133 | + sig_field = base64.b64decode(m["TLS.sig"]) |
| 134 | + ret = OpenSSL.crypto.verify(pubkey_loaded, sig_field, fix_str, "sha256") |
| 135 | + print(ret) |
| 136 | + |
| 137 | +def main(): |
| 138 | + api = TLSSigAPI(1400001052, ecdsa_pri_key, ecdsa_pub_key) |
| 139 | + sig = api.tls_gen_sig("xiaojun") |
| 140 | + print(sig) |
| 141 | + |
| 142 | + |
| 143 | +if __name__ == "__main__": |
| 144 | + main() |
0 commit comments