Skip to content

Commit 780355f

Browse files
authored
Remove dependency on pycryptodome (#17)
* Remove dependancy on PyCryptodome (Martin's code) * Minor fix to signature verification * Update setup.py
1 parent 2107ab4 commit 780355f

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

licensing/internal.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
@author: Artem Los
66
"""
77
import base64
8-
from Crypto.Signature import PKCS1_v1_5
9-
from Crypto.Hash import SHA256
10-
from Crypto.PublicKey import RSA
118
import urllib.request
129
import hashlib
1310
from subprocess import Popen, PIPE
@@ -23,16 +20,67 @@ def get_SHA256(string):
2320
"""
2421
return hashlib.sha256(string.encode("utf-8")).hexdigest()
2522

23+
@staticmethod
24+
def I2OSP(x, xLen):
25+
if x > (1 << (8 * xLen)):
26+
return None
27+
Xrev = []
28+
for _ in range(0, xLen):
29+
x, m = divmod(x, 256)
30+
Xrev.append(m)
31+
return bytes(reversed(Xrev))
32+
33+
@staticmethod
34+
def OS2IP(X):
35+
import binascii
36+
h = binascii.hexlify(X)
37+
return int(h, 16)
38+
39+
@staticmethod
40+
def RSAVP1(pair, s):
41+
n, e = pair
42+
if s < 0 or n-1 < s:
43+
return None
44+
return pow(s, e, n)
45+
46+
@staticmethod
47+
def EMSA_PKCS1_V15_ENCODE(M, emLen):
48+
import hashlib
49+
h = hashlib.sha256()
50+
h.update(M)
51+
H = h.digest()
52+
53+
T = bytes([0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20]) + H
54+
tLen = len(T)
55+
if emLen < tLen + 11:
56+
return None
57+
PS = bytes([0xff for _ in range(emLen - tLen - 3)])
58+
return b"".join([b"\x00\x01", PS, b"\x00", T])
59+
60+
@staticmethod
61+
def RSAASSA_PKCS1_V15_VERIFY(pair, M, S):
62+
n, e = pair
63+
s = HelperMethods.OS2IP(S)
64+
m = HelperMethods.RSAVP1((n,e), s)
65+
if m is None: return False
66+
EM = HelperMethods.I2OSP(m, 256)
67+
if EM is None: return False
68+
EM2 = HelperMethods.EMSA_PKCS1_V15_ENCODE(M, 256) # Can return None, but it's OK since EM is not None
69+
return EM == EM2
70+
2671
@staticmethod
2772
def verify_signature(response, rsaPublicKey):
2873
"""
2974
Verifies a signature from .NET RSACryptoServiceProvider.
3075
"""
31-
cryptoPubKey = RSA.construct((HelperMethods.base642int(rsaPublicKey.modulus),\
32-
HelperMethods.base642int(rsaPublicKey.exponent)))
33-
h = SHA256.new(base64.b64decode(response.license_key.encode("utf-8")))
34-
verifier = PKCS1_v1_5.new(cryptoPubKey)
35-
return verifier.verify(h, base64.b64decode(response.signature.encode("utf-8")))
76+
77+
n = HelperMethods.OS2IP(base64.b64decode(rsaPublicKey.modulus))
78+
e = HelperMethods.OS2IP(base64.b64decode(rsaPublicKey.exponent))
79+
80+
m = base64.b64decode(response.license_key)
81+
r = base64.b64decode(response.signature)
82+
83+
return HelperMethods.RSAASSA_PKCS1_V15_VERIFY((n,e), m, r)
3684

3785
@staticmethod
3886
def int2base64(num):

setup.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22
setup(
33
name = 'licensing', # How you named your package folder (MyLib)
44
packages = ['licensing'], # Chose the same as "name"
5-
version = '0.12', # Start with a small number and increase it with every change you make
5+
version = '0.13', # Start with a small number and increase it with every change you make
66
license='MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository
77
description = 'Client library for Cryptolens licensing Web API.', # Give a short description about your library
88
author = 'Cryptolens AB', # Type in your name
99
author_email = '[email protected]', # Type in your E-Mail
1010
url = 'https://cryptolens.io', # Provide either the link to your github or to your website
11-
download_url = 'https://github.com/Cryptolens/cryptolens-python/archive/v_12.tar.gz', # I explain this later on
11+
download_url = 'https://github.com/Cryptolens/cryptolens-python/archive/v_13.tar.gz', # I explain this later on
1212
keywords = ['software licensing', 'licensing library', 'cryptolens'], # Keywords that define your package best
13-
install_requires=[ # I get to this in a second
14-
'pycryptodome'
15-
],
1613
classifiers=[
1714
#'Development Status :: 5 - Stable', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
1815
'Intended Audience :: Developers', # Define that your audience are developers

0 commit comments

Comments
 (0)