Files
cocoafob/python/cocoafob.py
T
2020-09-30 01:24:28 +10:00

60 lines
2.6 KiB
Python

import base64
from OpenSSL import crypto # requires at least version 0.15.2 (or the latest version from GitHub, as this one is not yet released as of 2015/11/11)
# Creates a source string to generate the registration code with.
# A source string the contains product code name and the user's registration name,
# separated by a comma.
def make_license_source(product_code, name):
return (product_code + ',' + name).encode('utf8')
# This method generates a registration code. It receives your private key,
# a product code string and a registration name.
def make_license(private_key_string, product_code, name):
private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, private_key_string)
signature = crypto.sign(private_key, make_license_source(product_code, name), 'sha1')
# Use sha1 instead of dss1 to avoid 'ValueError("No such digest method")'
encoded_signature = base64.b32encode(signature).decode('utf8')
# Replace 'O' with 8, 'I' with 9
# See http://members.shaw.ca/akochoi-old/blog/2004/11-07/index.html
encoded_signature = encoded_signature.replace('O', '8').replace('I', '9')
# Remove equal signs
encoded_signature = encoded_signature.replace('=', '')
# Insert a dash every 5 characters
encoded_signature = '-'.join([encoded_signature[i:i+5] for i in range(0, len(encoded_signature), 5)])
return encoded_signature
def verify_license(public_key_string, encoded_signature, product_code, name):
base32_signature = encoded_signature.replace('8', 'O').replace('9', 'I').replace('-', '')
base32_signature += '=' * (8 - (len(base32_signature) % 8))
decoded_signature = base64.b32decode(base32_signature)
public_key = crypto.load_publickey(crypto.FILETYPE_PEM, public_key_string)
certificate = crypto.X509()
certificate.set_pubkey(public_key)
try:
crypto.verify(certificate, decoded_signature, make_license_source(product_code, name), 'sha1')
# Use sha1 instead of dss1 to avoid 'ValueError("No such digest method")'
return True
except:
return False
def main():
with open('../keys/privkey.pem') as keyfile:
private_key_string = keyfile.read()
with open('../keys/pubkey.pem') as keyfile:
public_key_string = keyfile.read()
# test generation
license = make_license(private_key_string, 'product', 'user')
print ('license is ' + license)
# test verification
assert(verify_license(public_key_string, license, 'product', 'user')) # This throws on an invalid license
print ('verification successful')
# test rejection of invalid signature
assert(not verify_license(public_key_string, license, 'product', 'WRONGUSER'))
print ('rejection successful')
if __name__ == '__main__':
main()