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