diff --git a/httpsig.py b/httpsig.py index a1d852284..2b0c9eb1b 100644 --- a/httpsig.py +++ b/httpsig.py @@ -19,17 +19,12 @@ import base64 from time import gmtime, strftime import datetime from utils import getFullDomain - - -def _getSHA256(msg: str): - digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) - digest.update(msg) - return digest.finalize() +from utils import getSHA256 def messageContentDigest(messageBodyJsonStr: str) -> str: msg = messageBodyJsonStr.encode('utf-8') - hashResult = _getSHA256(msg) + hashResult = getSHA256(msg) return base64.b64encode(hashResult).decode('utf-8') @@ -80,7 +75,7 @@ def signPostHeaders(dateStr: str, privateKeyPem: str, signedHeaderText += f'{headerKey}: {headers[headerKey]}\n' signedHeaderText = signedHeaderText.strip() # signedHeaderText.encode('ascii') matches - headerDigest = _getSHA256(signedHeaderText.encode('ascii')) + headerDigest = getSHA256(signedHeaderText.encode('ascii')) # print('headerDigest2: ' + str(headerDigest)) # Sign the digest @@ -252,7 +247,7 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict, print('DEBUG: signedHeaderList: ' + str(signedHeaderList)) # Now we have our header data digest signedHeaderText = '\n'.join(signedHeaderList) - headerDigest = _getSHA256(signedHeaderText.encode('ascii')) + headerDigest = getSHA256(signedHeaderText.encode('ascii')) # Get the signature, verify with public key, return result signature = base64.b64decode(signatureDict['signature']) diff --git a/linked_data_sig.py b/linked_data_sig.py index 9f4b009a7..5a1c5dbdd 100644 --- a/linked_data_sig.py +++ b/linked_data_sig.py @@ -11,18 +11,15 @@ __status__ = "Production" import base64 import hashlib from datetime import datetime - -try: - from Cryptodome.PublicKey import RSA - from Cryptodome.Hash import SHA256 - from Cryptodome.Signature import pkcs1_5 as PKCS1_v1_5 -except ImportError: - from Crypto.PublicKey import RSA - from Crypto.Hash import SHA256 - from Crypto.Signature import PKCS1_v1_5 - +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import load_pem_private_key +from cryptography.hazmat.primitives.serialization import load_pem_public_key +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import utils as hazutils from pyjsonld import normalize from context import hasValidContext +from utils import getSHA256 def _options_hash(doc: {}) -> str: @@ -73,14 +70,23 @@ def verifyJsonSignature(doc: {}, publicKeyPem: str) -> bool: """ if not hasValidContext(doc): return False - key = RSA.importKey(publicKeyPem) + pubkey = load_pem_public_key(publicKeyPem.encode('utf-8'), + backend=default_backend()) to_be_signed = _options_hash(doc) + _doc_hash(doc) signature = doc["signature"]["signatureValue"] - signer = PKCS1_v1_5.new(key) # type: ignore - digest = SHA256.new() - digest.update(to_be_signed.encode("utf-8")) + + digest = getSHA256(to_be_signed.encode("utf-8")) base64sig = base64.b64decode(signature) - return signer.verify(digest, base64sig) # type: ignore + + try: + pubkey.verify( + base64sig, + digest, + padding.PKCS1v15(), + hazutils.Prehashed(hashes.SHA256())) + return True + except BaseException: + return False def generateJsonSignature(doc: {}, privateKeyPem: str) -> None: @@ -98,9 +104,11 @@ def generateJsonSignature(doc: {}, privateKeyPem: str) -> None: doc["signature"] = options to_be_signed = _options_hash(doc) + _doc_hash(doc) - key = RSA.importKey(privateKeyPem) - signer = PKCS1_v1_5.new(key) - digest = SHA256.new() - digest.update(to_be_signed.encode("utf-8")) - sig = base64.b64encode(signer.sign(digest)) # type: ignore + key = load_pem_private_key(privateKeyPem.encode('utf-8'), + None, backend=default_backend()) + digest = getSHA256(to_be_signed.encode("utf-8")) + signature = key.sign(digest, + padding.PKCS1v15(), + hazutils.Prehashed(hashes.SHA256())) + sig = base64.b64encode(signature) options["signatureValue"] = sig.decode("utf-8") diff --git a/utils.py b/utils.py index 34c5773b4..3e7c8c4ec 100644 --- a/utils.py +++ b/utils.py @@ -18,6 +18,16 @@ import idna from pprint import pprint from calendar import monthrange from followingCalendar import addPersonToCalendar +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes + + +def getSHA256(msg: str): + """Returns a SHA256 hash of the given string + """ + digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) + digest.update(msg) + return digest.finalize() def _localNetworkHost(host: str) -> bool: