1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| import base64 import json
from Crypto.Hash import SHA1, SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import pkcs1_15 from Crypto.Util.asn1 import DerSequence, DerObjectId, DerNull, DerOctetString from cryptography import x509 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import serialization
ROOT_CERTIFICATES = ("MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV\n" + "BAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2\n" + "WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOC\n" + "Ag8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYG\n" + "y+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBl\n" + "m5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNX\n" + "EpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8bo\n" + "iwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVA\n" + "xoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOw\n" + "jzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52F\n" + "LcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXr\n" + "SopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZM\n" + "Q9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXR\n" + "Rus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEA\n" + "AaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEw\n" + "P4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2Zp\n" + "bGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq\n" + "hkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpK\n" + "BMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7o\n" + "uLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6\n" + "hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlL\n" + "S9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+n\n" + "fDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPk\n" + "X+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn\n" + "8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB\n" + "/gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me\n" + "0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujl\n" + "FeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU=\n")
def create_power_file(active_code): subcert = x509.load_der_x509_certificate(base64.b64decode(active_code.split('-')[3])) s = int.from_bytes(subcert.signature, byteorder='big', signed=False)
digest_cert = SHA256.new(subcert.tbs_certificate_bytes) digest_info = create_digest_info(digest_cert)
key_size_bytes = subcert.public_key().key_size // 8 padded_data = create_pkcs1v15_padding(digest_info, key_size_bytes) r = int.from_bytes(padded_data, byteorder='big', signed=False) with open('power.conf', 'w', encoding='utf-8') as f: jb_ca = x509.load_der_x509_certificate(base64.b64decode(ROOT_CERTIFICATES)) jb_ca_public_key = jb_ca.public_key() jb_ca_public_key_n = jb_ca_public_key.public_numbers().n jb_ca_public_key_e = jb_ca_public_key.public_numbers().e
f.write("[Result]\n") f.write(f"EQUAL,{s},{jb_ca_public_key_e},{jb_ca_public_key_n}->{r}")
def create_digest_info(hash_obj): algorithm_id = DerSequence([ DerObjectId(hash_obj.oid), DerNull() ]) digest_info = DerSequence([ algorithm_id, DerOctetString(hash_obj.digest()) ]) return digest_info.encode()
def create_pkcs1v15_padding(digest_info, key_size_bytes): padding_length = key_size_bytes - len(digest_info) - 3 if padding_length < 8: raise ValueError(f"Key size ({key_size_bytes * 8} bits) too small for hash digest") return b'\x00\x01' + b'\xff' * padding_length + b'\x00' + digest_info
with open('ca.cer', 'rb') as cert_file: cert = x509.load_pem_x509_certificate(cert_file.read()) cert_der = cert.public_bytes(encoding=serialization.Encoding.DER) my_cert_content = base64.b64encode(cert_der).decode('utf-8')
with open('license.json', 'r', encoding='utf-8') as f: license_config = json.load(f)
licenseId = license_config['licenseId'] licensePart = json.dumps(license_config)
with open('ca.key') as prifile: private_key = RSA.import_key(prifile.read()) digest = SHA1.new(licensePart.encode('utf-8')) signature = pkcs1_15.new(private_key).sign(digest)
sig_results = base64.b64encode(signature) licensePartBase64 = base64.b64encode(licensePart.encode('utf-8'))
cert.public_key().verify( base64.b64decode(sig_results), base64.b64decode(licensePartBase64), padding=padding.PKCS1v15(), algorithm=hashes.SHA1(), )
active_code = licenseId + "-" + licensePartBase64.decode('utf-8') + "-" + sig_results.decode('utf-8') + "-" + my_cert_content with open('key.txt', 'w', encoding='utf-8') as f: f.write(active_code)
create_power_file(active_code)
|