add rsa
Showing
8 changed files
with
243 additions
and
2 deletions
1 | ## 保护源码:py2so.py | 1 | ## 鉴权与保护 |
2 | ### 0. 运行环境 | ||
3 | - python3 | ||
4 | - pip install -r requirements.txt | ||
5 | |||
6 | ### 1. 鉴权(服务端): verify.py | ||
7 | - 生成公私钥对 | ||
8 | ``` | ||
9 | python RSA/create_keys.py | ||
10 | ``` | ||
11 | - 根据过期日期(必须)和MAC地址(可选, en0),通过私钥加密,生成认证文件 | ||
12 | - help text | ||
13 | ``` | ||
14 | ❯ python RSA/encrypt.py -h | ||
15 | usage: encrypt.py [-h] -d DATE [-m MAC] | ||
16 | |||
17 | encrypt expire date & mac address with private key | ||
18 | |||
19 | optional arguments: | ||
20 | -h, --help show this help message and exit | ||
21 | -d DATE, --date DATE expire date. eg: 2020-06-06 | ||
22 | -m MAC, --mac MAC mac address | ||
23 | ``` | ||
24 | - example | ||
25 | ``` | ||
26 | python RSA/encrypt.py -d 2021-01-12 -m 38:f9:d3:2e:c0:f3 | ||
27 | ``` | ||
28 | - 项目使用 | ||
29 | - 拷贝以下文件至项目 | ||
30 | - 公钥:RSA/public.pem | ||
31 | - 认证文件:RSA/certification.cert | ||
32 | - 验证脚本:verify.py | ||
33 | - 使用验证脚本鉴权 | ||
34 | ``` | ||
35 | from verify import verify | ||
36 | is_valid = verify(path_to_public_key, path_to_cert) | ||
37 | if is_valid: | ||
38 | print('verify success') | ||
39 | else: | ||
40 | print('verify failed') | ||
41 | ``` | ||
42 | |||
43 | ### 2. 保护源码:py2so.py | ||
44 | - description | ||
45 | ```angular2html | ||
46 | compile the .py to .so(Linux/Mac) or .pdy(Win) | ||
47 | ``` | ||
2 | - help text | 48 | - help text |
3 | ``` | 49 | ``` |
4 | ❯ python py2so.py -h | 50 | ❯ python py2so.py -h | ... | ... |
RSA/consts.py
0 → 100644
RSA/create_keys.py
0 → 100644
1 | import os | ||
2 | from Crypto.PublicKey import RSA | ||
3 | from consts import PRIVATE_KEY_NAME, PUBLIC_KEY_NAME | ||
4 | |||
5 | |||
6 | def create_keys(private_key_path, public_key_path): | ||
7 | keys = RSA.generate(bits=4096) | ||
8 | with open(private_key_path, "wb") as private_fp: | ||
9 | private_fp.write(keys.export_key('PEM')) | ||
10 | |||
11 | with open(public_key_path, "wb") as public_fp: | ||
12 | public_fp.write(keys.publickey().export_key('PEM')) | ||
13 | |||
14 | |||
15 | def main(): | ||
16 | output_dir = os.path.dirname(os.path.abspath(__file__)) | ||
17 | private_key_path = os.path.join(output_dir, PRIVATE_KEY_NAME) | ||
18 | public_key_path = os.path.join(output_dir, PUBLIC_KEY_NAME) | ||
19 | create_keys(private_key_path, public_key_path) | ||
20 | |||
21 | |||
22 | if __name__ == '__main__': | ||
23 | main() |
RSA/encrypt.py
0 → 100644
1 | import os | ||
2 | import random | ||
3 | import argparse | ||
4 | from datetime import datetime | ||
5 | from Crypto.PublicKey import RSA | ||
6 | from consts import PRIVATE_KEY_NAME, CERT_NAME, SPLIT_CHAR, DEFAULT_MAC | ||
7 | |||
8 | |||
9 | parser = argparse.ArgumentParser(description='encrypt expire date & mac address with private key') | ||
10 | parser.add_argument('-d', '--date', help='expire date. eg: 2020-06-06', required=True) | ||
11 | parser.add_argument('-m', '--mac', default=DEFAULT_MAC, help='mac address') | ||
12 | args = parser.parse_args() | ||
13 | |||
14 | |||
15 | def get_exponent_and_modulus(private_key_path): | ||
16 | with open(private_key_path, 'r') as private_fp: | ||
17 | private_key = RSA.import_key(private_fp.read()) | ||
18 | return private_key.d, private_key.n | ||
19 | |||
20 | |||
21 | def get_encrypt_int(mac, expire_date): | ||
22 | encrypt_bytes = "{0}{3}{1}{3}{2}".format(mac, str(random.random()), expire_date, SPLIT_CHAR).encode('utf-8') | ||
23 | return int.from_bytes(encrypt_bytes, byteorder='big') | ||
24 | |||
25 | |||
26 | def main(): | ||
27 | try: | ||
28 | expire_date = datetime.strptime(args.date, '%Y-%m-%d') | ||
29 | except Exception as e: | ||
30 | print('expire date format error. eg: 2020-06-06') | ||
31 | return | ||
32 | |||
33 | if datetime.today() >= expire_date: | ||
34 | print('expire date must later than today') | ||
35 | return | ||
36 | |||
37 | base_dir = os.path.dirname(os.path.abspath(__file__)) | ||
38 | private_key_path = os.path.join(base_dir, PRIVATE_KEY_NAME) | ||
39 | output_path = os.path.join(base_dir, CERT_NAME) | ||
40 | |||
41 | encrypt_int = get_encrypt_int(args.mac, args.date) | ||
42 | d, n = get_exponent_and_modulus(private_key_path) | ||
43 | signature = pow(encrypt_int, d, n) | ||
44 | |||
45 | with open(output_path, 'wb') as fp: | ||
46 | fp.write(str(signature).encode("utf-8")) | ||
47 | |||
48 | |||
49 | if __name__ == '__main__': | ||
50 | main() |
RSA/verify.py
0 → 100644
1 | import os | ||
2 | from getmac import get_mac_address | ||
3 | from datetime import datetime | ||
4 | from Crypto.PublicKey import RSA | ||
5 | from consts import PUBLIC_KEY_NAME, CERT_NAME, SPLIT_CHAR, DEFAULT_MAC | ||
6 | |||
7 | |||
8 | def get_exponent_and_modulus(public_key_path): | ||
9 | with open(public_key_path, 'r') as public_fp: | ||
10 | public_key = RSA.import_key(public_fp.read()) | ||
11 | return public_key.e, public_key.n | ||
12 | |||
13 | |||
14 | def get_signature(cert_path): | ||
15 | with open(cert_path, 'r') as fp: | ||
16 | signature = fp.read() | ||
17 | return int(signature) | ||
18 | |||
19 | |||
20 | def is_expire(expire_date_str): | ||
21 | expire_date = datetime.strptime(expire_date_str, '%Y-%m-%d') | ||
22 | if datetime.today() >= expire_date: | ||
23 | return True | ||
24 | return False | ||
25 | |||
26 | |||
27 | def is_valid_mac(mac): | ||
28 | if mac == DEFAULT_MAC: | ||
29 | return True | ||
30 | if mac == get_mac_address(): | ||
31 | return True | ||
32 | return False | ||
33 | |||
34 | |||
35 | def verify(public_key_path, cert_path): | ||
36 | try: | ||
37 | e, n = get_exponent_and_modulus(public_key_path) | ||
38 | signature = get_signature(cert_path) | ||
39 | encrypt_int = pow(signature, e, n) | ||
40 | encrypt_str = encrypt_int.to_bytes(length=encrypt_int.bit_length() // 8 + 1, byteorder='big').decode() | ||
41 | mac, _, expire_date_str = encrypt_str.split(SPLIT_CHAR) | ||
42 | if is_expire(expire_date_str) or not is_valid_mac(mac): | ||
43 | return False | ||
44 | return True | ||
45 | except Exception as e: | ||
46 | print('verify error: {0}'.format(e)) | ||
47 | return False | ||
48 | |||
49 | |||
50 | if __name__ == '__main__': | ||
51 | base_dir = os.path.dirname(os.path.abspath(__file__)) | ||
52 | public_key_path = os.path.join(base_dir, PUBLIC_KEY_NAME) | ||
53 | cert_path = os.path.join(base_dir, CERT_NAME) | ||
54 | |||
55 | is_valid = verify(public_key_path, cert_path) | ||
56 | if is_valid: | ||
57 | print('verify success') | ||
58 | else: | ||
59 | print('verify failed') |
verify.py
0 → 100644
1 | from getmac import get_mac_address | ||
2 | from datetime import datetime | ||
3 | from Crypto.PublicKey import RSA | ||
4 | |||
5 | |||
6 | SPLIT_CHAR = "+" | ||
7 | DEFAULT_MAC = "pass" | ||
8 | |||
9 | |||
10 | def get_exponent_and_modulus(public_key_path): | ||
11 | with open(public_key_path, 'r') as public_fp: | ||
12 | public_key = RSA.import_key(public_fp.read()) | ||
13 | return public_key.e, public_key.n | ||
14 | |||
15 | |||
16 | def get_signature(cert_path): | ||
17 | with open(cert_path, 'r') as fp: | ||
18 | signature = fp.read() | ||
19 | return int(signature) | ||
20 | |||
21 | |||
22 | def is_expire(expire_date_str): | ||
23 | expire_date = datetime.strptime(expire_date_str, '%Y-%m-%d') | ||
24 | if datetime.today() >= expire_date: | ||
25 | return True | ||
26 | return False | ||
27 | |||
28 | |||
29 | def is_valid_mac(mac): | ||
30 | if mac == DEFAULT_MAC: | ||
31 | return True | ||
32 | if mac == get_mac_address(): | ||
33 | return True | ||
34 | return False | ||
35 | |||
36 | |||
37 | def verify(public_key_path, cert_path): | ||
38 | try: | ||
39 | e, n = get_exponent_and_modulus(public_key_path) | ||
40 | signature = get_signature(cert_path) | ||
41 | encrypt_int = pow(signature, e, n) | ||
42 | encrypt_str = encrypt_int.to_bytes(length=encrypt_int.bit_length() // 8 + 1, byteorder='big').decode() | ||
43 | mac, _, expire_date_str = encrypt_str.split(SPLIT_CHAR) | ||
44 | if is_expire(expire_date_str) or not is_valid_mac(mac): | ||
45 | return False | ||
46 | return True | ||
47 | except Exception as e: | ||
48 | print('verify error: {0}'.format(e)) | ||
49 | return False | ||
50 |
-
Please register or sign in to post a comment