mirror of
https://github.com/glebd/cocoafob.git
synced 2026-05-30 14:46:50 +00:00
60 lines
2.6 KiB
Python
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()
|