def generate_dh_public_key(self): # Generate DH key pair print('Generating DH public/private key pair') self.dh_private_key = ec.generate_private_key(ec.SECP256R1, default_backend()) self.dh_public_key = self.dh_private_key.public_key() # Sign DH public key print('signing public key DH with private key') signature = self.kr.sign( self.dh_public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ), ec.ECDSA(hashes.SHA256()) ) return (self.dh_public_key, signature)
def recover_public_key(digest, signature, i, message=None): """ Recover the public key from the the signature """ # See http: //www.secg.org/download/aid-780/sec1-v2.pdf section 4.1.6 primarily curve = ecdsa.SECP256k1.curve G = ecdsa.SECP256k1.generator order = ecdsa.SECP256k1.order yp = (i % 2) r, s = ecdsa.util.sigdecode_string(signature, order) # 1.1 x = r + (i // 2) * order # 1.3. This actually calculates for either effectively 02||X or 03||X depending on 'k' instead of always for 02||X as specified. # This substitutes for the lack of reversing R later on. -R actually is defined to be just flipping the y-coordinate in the elliptic curve. alpha = ((x * x * x) + (curve.a() * x) + curve.b()) % curve.p() beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p()) y = beta if (beta - yp) % 2 == 0 else curve.p() - beta # 1.4 Constructor of Point is supposed to check if nR is at infinity. R = ecdsa.ellipticcurve.Point(curve, x, y, order) # 1.5 Compute e e = ecdsa.util.string_to_number(digest) # 1.6 Compute Q = r^-1(sR - eG) Q = ecdsa.numbertheory.inverse_mod(r, order) * (s * R + (-e % order) * G) if SECP256K1_MODULE == "cryptography" and message is not None: if not isinstance(message, bytes_types): message = py23_bytes(message, "utf-8") sigder = encode_dss_signature(r, s) try: Q_point = Q.to_affine() public_key = ec.EllipticCurvePublicNumbers( Q_point.x(), Q_point.y(), ec.SECP256K1()).public_key(default_backend()) except: public_key = ec.EllipticCurvePublicNumbers( Q._Point__x, Q._Point__y, ec.SECP256K1()).public_key(default_backend()) public_key.verify(sigder, message, ec.ECDSA(hashes.SHA256())) return public_key else: # Not strictly necessary, but let's verify the message for paranoia's sake. if not ecdsa.VerifyingKey.from_public_point( Q, curve=ecdsa.SECP256k1).verify_digest( signature, digest, sigdecode=ecdsa.util.sigdecode_string): return None return ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.SECP256k1)
def verify_sign(inputbuf, keybuf, signbuf, digest, ecosystem): pkey = serialization.load_pem_public_key(keybuf, backend=default_backend()) hash = hashes.SHA256() if digest == 'SHA256' else hashes.SHA512() try: if ecosystem == 'RSA': pkey.verify( signbuf, inputbuf, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hash) else: pkey.verify(signbuf, inputbuf, ec.ECDSA(hash)) except InvalidSignature: return 'Verification Failed' return 'Verification Succeed'
def verify(public_key, data, signature): """ Verify a signature based on the original public key and data """ deserialized_public_key = serialization.load_pem_public_key( public_key.encode("utf-8"), default_backend()) r, s = signature try: deserialized_public_key.verify(encode_dss_signature(r, s), json.dumps(data).encode("utf-8"), ec.ECDSA(hashes.SHA256())) return True except InvalidSignature: return False
def verify_request_sig(raw_cert, sig, req, request_body, md): cert = x509.load_pem_x509_certificate(raw_cert, backend=default_backend()) # Verify that the request digest matches the hash of the body h = hashes.Hash(hashes.SHA256(), backend=default_backend()) h.update(request_body) raw_req_digest = h.finalize() header_digest = base64.b64decode(req.decode().split("SHA-256=")[1]) assert header_digest == raw_req_digest, "Digest header does not match request body" pub_key = cert.public_key() signature_hash_alg = ec.ECDSA( hashes.SHA256() if CCFDigestType[md] == CCFDigestType.SHA256 else cert.signature_hash_algorithm ) pub_key.verify(sig, req, signature_hash_alg)
def sign_data(self, data: bytes) -> bytes: """ CA 개인키로 DATA 서명 :param data: 서명 대상 원문 :return: 서명 """ if isinstance(self.__ca_pri, ec.EllipticCurvePrivateKeyWithSerialization): signer = self.__ca_pri.signer(ec.ECDSA(hashes.SHA256())) signer.update(data) return signer.finalize() elif isinstance(self.__ca_pri, rsa.RSAPrivateKeyWithSerialization): return self.__ca_pri.sign(data, padding.PKCS1v15(), hashes.SHA256()) else: logging.debug("Unknown PrivateKey Type : %s", type(self.__ca_pri)) return None
def verifySignatureEC(signature, message, client, key_path): """ Verify the validity of an 'EC_SIGN_P256_SHA256' signature for the specified message """ public_key = getAsymmetricPublicKey(client, key_path) digest_bytes = hashlib.sha256(message).digest() try: # Attempt verification public_key.verify(signature, digest_bytes, ec.ECDSA(utils.Prehashed(hashes.SHA256()))) # No errors were thrown. Verification was successful return True except InvalidSignature: return False
def sign(self, payload): """ Sign a payload :param payload: String (usually jwt payload) :return: URL safe base64 signature """ signature = self._private_key.sign(utils.to_bytes(payload), ec.ECDSA(hashes.SHA256())) r, s = decode_dss_signature(signature) br = int_to_bytes(r, KEYSIZE_BYTES) bs = int_to_bytes(s, KEYSIZE_BYTES) str_sig = br + bs b64_signature = utils.base64url_encode(str_sig) return b64_signature
def verify_message(msg, key, sig): """ msg - message as string key - public key generated by generate_asymm_key() sig - signature as bytes output - True if signature valid, False otherwise """ try: key.verify(sig, msg.encode(), ec.ECDSA(hashes.SHA256())) except InvalidSignature: return False return True # msg1 = "Hello World!" # msg2 = "Hello!" # (pr_key1, pub_key1, s_pr_key1, s_pub_key1) = generate_asymm_key() # (pr_key2, pub_key2) = generate_asymm_key() # for i in range(4): # (_, _, s_pr_key, s_pub_key) = generate_asymm_key() # print(str(s_pr_key)) # print(str(s_pub_key)) # print("") # sig11 = sign_message(msg1, pr_key1) # sig12 = sign_message(msg2, pr_key1) # s_sig11 = sign_message(msg1, load_asymm_pr_key(s_pr_key1)) # s_sig12 = sign_message(msg2, load_asymm_pr_key(s_pr_key1)) # sig21 = sign_message(msg1, pr_key2) # sig22 = sign_message(msg2, pr_key2) # print(verify_message(msg1, pub_key1, sig11)) # print(verify_message(msg2, pub_key1, sig12)) # print(verify_message(msg1, pub_key1, s_sig11)) # print(verify_message(msg2, pub_key1, s_sig12)) # print(verify_message(msg1, load_asymm_pub_key(s_pub_key1), sig11)) # print(verify_message(msg2, load_asymm_pub_key(s_pub_key1), sig12)) # print(verify_message(msg1, pub_key2, sig21)) # print(verify_message(msg2, pub_key2, sig22)) # print(verify_message(msg1, pub_key2, sig11)) # print(verify_message(msg2, pub_key2, sig12)) # print(verify_message(msg1, pub_key1, sig21)) # print(verify_message(msg2, pub_key1, sig22))
def verify(public_key, data, signature): """ Verify a signature based on the original public key and data. """ deserialized_public_key = serialization.load_pem_public_key( public_key.encode('utf-8'), default_backend()) # signature is tuple type, assigning first value to r, and second to s (r, s) = signature try: deserialized_public_key.verify(encode_dss_signature(r, s), json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256())) return True except InvalidSignature: return False
def test_checkdatasig(self): with self.assertRaises(MissingStackItems): op_checkdatasig([1, 1], log=[], extras=None) data = b'some_random_data' signature = self.genesis_private_key.sign(data, ec.ECDSA(hashes.SHA256())) pubkey_bytes = get_public_key_bytes_compressed(self.genesis_public_key) stack = [data, signature, pubkey_bytes] # no exception should be raised and data is left on stack op_checkdatasig(stack, log=[], extras=None) self.assertEqual(data, stack.pop()) stack = [b'data_not_matching', signature, pubkey_bytes] with self.assertRaises(OracleChecksigFailed): op_checkdatasig(stack, log=[], extras=None)
def verify(self, message: bytes, verifying_key: UmbralPublicKey) -> bool: """ Verifies that a message's signature was valid. :param message: The message to verify :param pubkey: UmbralPublicKey of the signer :return: True if valid, False if invalid """ cryptography_pub_key = verifying_key.to_cryptography_pubkey() try: cryptography_pub_key.verify(self._der_encoded_bytes(), message, ec.ECDSA(_BLAKE2B)) except InvalidSignature: return False return True
def validate_and_extract_assertion(token, key): # type (str, str) -> JSONDict """Decode a web token into a assertion dictionary. This attempts to rectify both ecdsa and openssl generated signatures. We use the built-in cryptography library since it wraps libssl and is faster than the python only approach. :param token: VAPID auth token :type token: str :param key: bitarray containing public key :type key: str or bitarray :return dict of the VAPID claims :raise InvalidSignature """ # convert the signature if needed. try: sig_material, signature = VerifyJWT.extract_signature(token) pkey = ec.EllipticCurvePublicNumbers.from_encoded_point( ec.SECP256R1(), key).public_key(default_backend()) # cffi issue #320: public_key & verify allocate approx. if _JWT_MEMORY_PRESSURE: # pragma: nocover add_memory_pressure(_JWT_MEMORY_PRESSURE) # NOTE: verify() will take any string as the signature. It appears # to be doing lazy verification and matching strings rather than # comparing content values. If the signatures start failing for # some unknown reason in the future, decode the signature and # make sure it matches how we're reconstructing it. # This will raise an InvalidSignature exception if failure. # It will be captured externally. pkey.verify(signature, sig_material.encode('utf8'), ec.ECDSA(hashes.SHA256())) return VerifyJWT.extract_assertion(sig_material) except InvalidSignature: raise except (ValueError, TypeError, binascii.Error, PyAsn1Error): raise InvalidSignature() except Exception: # pragma: no cover Logger().failure("Unexpected error processing JWT") raise InvalidSignature()
def sign(self, message: Text, pad=None, hashing: HashAlgorithm = hashes.SHA256()) -> bytes: """ Generate a signature for a given message using the loaded :py:attr:`.private_key`. The signature is Base64 encoded to allow for easy storage and transmission of the signature, and can later be verified by :py:meth:`.verify` using :py:attr:`.public_key` >>> km = KeyManager.load_keyfile('id_rsa') >>> sig = km.sign('hello world') # Sign 'hello world' using the id_rsa private key >>> try: ... km.verify(sig, 'hello world') # Verify it using the public key (automatically generated) ... print('Signature is valid') >>> except cryptography.exceptions.InvalidSignature: ... print('Signature IS NOT VALID!') Alternatively, you can manually run :py:func:`base64.urlsafe_b64decode` to decode the signature back into raw bytes, then you can verify it using the ``verify`` method of a ``cryptography`` public key instance, such as :class:`.Ed25519PublicKey` or :class:`.RSAPublicKey` :param str|bytes message: The message to verify, e.g. ``hello world`` :param pad: (RSA only) An instance of a cryptography padding class, e.g. :class:`.padding.PSS` :param HashAlgorithm hashing: (ECDSA/RSA) Use this hashing method for padding/signatures :raises cryptography.exceptions.InvalidSignature: When the signature does not match the message :return bytes sig: A base64 urlsafe encoded signature """ message = byteify(message) if isinstance(self.private_key, Ed25519PrivateKey): return base64.urlsafe_b64encode( self.private_key.sign(data=message)) if isinstance(self.private_key, ec.EllipticCurvePrivateKey): return base64.urlsafe_b64encode( self.private_key.sign(message, ec.ECDSA(hashing))) # Fallback: RSA with padding if not pad: pad = padding.PSS(mgf=padding.MGF1(hashing), salt_length=padding.PSS.MAX_LENGTH) return base64.urlsafe_b64encode( self.private_key.sign(data=message, padding=pad, algorithm=hashing))
def verify_signature(key, sig, file): """ Verify the file signature (sig) using a public key (key) with the file (file). """ # Inspect the public key to determine what kind of key it is. key_header = key.decode("utf-8").split("\n")[0].strip() # PGP if key_header == "-----BEGIN PGP PUBLIC KEY BLOCK-----": gpg = gnupg.GPG() logger.debug("Importing GPG key") gpg_imported = gpg.import_keys(key.decode("utf-8")) if gpg_imported.count == 1: # pylint: disable=E1101 logger.debug("GPG key successfully imported") else: raise Exception("Unable to import GPG key") # The Python PGP library won't let you read a signature from memory, hence this hack. with tempfile.NamedTemporaryFile() as temp_sig: temp_sig.write(sig) temp_sig.flush() verified = gpg.verify_data(temp_sig.name, file) # OpenSSL elif key_header == "-----BEGIN PUBLIC KEY-----": logger.debug("Importing ECDSA key") pubkey = load_pem_public_key(key) if isinstance(pubkey, ec.EllipticCurvePublicKey): logger.debug( "EC public key successfully imported, verifying signature...") try: pubkey.verify(sig, file, ec.ECDSA(hashes.SHA256())) verified = True except InvalidSignature: verified = False else: raise Exception( f"Unsupported public key algorithm: {type(pubkey)}") else: raise Exception("Unrecognized key type!") return verified
def test_set_signature(self): """Test updating a signature in a CSR.""" message = b"test" rsa_signature = self.rsa_private_key.sign( message, padding.PKCS1v15(), hashes.SHA256() ) dsa_signature = self.dsa_private_key.sign(message, hashes.SHA256()) ec_signature = self.ec_private_key.sign(message, ec.ECDSA(hashes.SHA256())) self.assertTrue(self.rsa_csr.is_signature_valid, "CSR should be valid") self.rsa_csr.set_signature(rsa_signature) self.assertFalse( self.rsa_csr.is_signature_valid, "CSR should no longer be valid after signature swap", ) self.assertEqual( self.rsa_csr.signature, rsa_signature, "Signature of CSR should match swapped signature", ) self.assertTrue(self.dsa_csr.is_signature_valid, "CSR should be valid") self.dsa_csr.set_signature(dsa_signature) self.assertFalse( self.dsa_csr.is_signature_valid, "CSR should no longer be valid after signature swap", ) self.assertEqual( self.dsa_csr.signature, dsa_signature, "Signature of CSR should match swapped signature", ) self.assertTrue(self.ec_csr.is_signature_valid, "CSR should be valid") self.ec_csr.set_signature(ec_signature) self.assertFalse( self.ec_csr.is_signature_valid, "CSR should no longer be valid after signature swap", ) self.assertEqual( self.ec_csr.signature, ec_signature, "Signature of CSR should match swapped signature", )
def verify(data: object, signature: str, public_key: str) -> bool: """ verfies message with digital signature @param message: (object) message to verify @param signature: (str) signature to verify message with @param public_key: (str) public key to verify message with """ try: public_key_bytes = serialization.load_pem_public_key( bytes.fromhex(public_key), backend=default_backend() ) signature_bytes = bytes.fromhex(signature) data_bytes = Helper.object_to_bytes(data) public_key_bytes.verify(signature_bytes, data_bytes, ec.ECDSA(hashes.SHA256())) return True except InvalidSignature: return False
def verify(public_key, data, signature): """ Verify a signature based on the original public key and data. """ # turn public key string backinto public key object deserialized_public_key = serialization.load_pem_public_key( public_key.encode('utf-8'), default_backend()) #print(f'\nsignature: {signature}\n') (r, s) = signature try: deserialized_public_key.verify(encode_dss_signature(r, s), json.dumps(data).encode('utf-8'), ec.ECDSA(hashes.SHA256())) return True except InvalidSignature: return False
def verify(public_key, data, signature): """ Verify a signature based on the original public key and data. """ # Assumption, data is not encoded-> convert to json deserialized_public_key = serialization.load_pem_public_key( public_key.encode('utf-8'), default_backend()) r, s = signature try: deserialized_public_key.verify( encode_dss_signature(r, s), json.dumps(data, sort_keys=True).encode('utf-8'), ec.ECDSA(hashes.SHA256())) return True except InvalidSignature: return False
def sign(claims, key): """Sign the claims :param claims: list of JWS claims :type claims: dict :param key: Private key for signing :type key: ec.EllipticCurvePrivateKey :param algorithm: JWT "alg" descriptor :type algorithm: str """ header = b64urlencode(b"""{"typ":"JWT","alg":"ES256"}""") claims = b64urlencode( json.dumps(claims, separators=(',', ':')).encode('utf8')) token = "{}.{}".format(header, claims) rsig = key.sign(token.encode('utf8'), ec.ECDSA(hashes.SHA256())) sig = b64urlencode(rsig) return "{}.{}".format(token, sig)
def verify(self, public_key, message, signature): """ECDSA verify signature. :param public_key: Signing public key :param message: Origin message :param signature: Signature of message :Returns: verify result boolean, True means valid """ verifier = public_key.verifier(signature, ec.ECDSA(self.sign_hash_algorithm)) verifier.update(message) try: verifier.verify() except InvalidSignature: return False except Exception as e: raise e return True
def verify(self, public_key, message, signature): """ECDSA verify signature. :param public_key: Signing public key :param message: Origin message :param signature: Signature of message :Returns: verify result boolean, True means valid """ if not (self._check_malleability(signature)): return False try: public_key.verify(signature, message, ec.ECDSA(self.sign_hash_algorithm)) except InvalidSignature: return False except Exception as e: raise e return True
def validate_signature(self, digest, signature): public_key = load_der_public_key(self.public_key, default_backend()) if len(signature) == 64: hash = hashes.SHA256() elif len(signature) == 96: hash = hashes.SHA384() signature = binascii.hexlify(signature) r = int(signature[:int(len(signature)/2)], 16) s = int(signature[int(len(signature)/2):], 16) encoded_sig = sigencode_der(r, s, len(signature)*4) try: public_key.verify(encoded_sig, digest, ec.ECDSA(Prehashed(hash))) return True except InvalidSignature: # TODO Fixme. This is what is expected today on the outer calls. This should be implementation independent # but requires changing everything calling that from ecdsa import BadSignatureError raise BadSignatureError
def gen_ecdsa(image, private_key): private_key = serialization.load_pem_private_key(private_key, password=None) chosen_hash = hashes.SHA256() hasher = hashes.Hash(chosen_hash) hasher.update(image) digest = hasher.finalize() print("SHA256 Image digest: {}".format(digest.hex())) signature = private_key.sign(digest, ec.ECDSA(utils.Prehashed(chosen_hash))) print("ECDSA signature: {}, len = {}".format(signature, len(signature))) (r, s) = utils.decode_dss_signature(signature) return r.to_bytes(32, byteorder='big') + s.to_bytes(32, byteorder='big')
def is_confirmed_integrity(self, data: bytes, signature: bytes, signer_pbk: str) -> bool: """ Confirrms the integrity of the data with respect to its signature. :param data: the data to be confirmed :param signature: the signature associated with the data :param signer_pbk: the public key of the signer :return: bool indicating whether the integrity is confirmed or not """ signer_pbk = self._pbk_b58_to_obj(signer_pbk) digest = self._hash_data(data) try: signer_pbk.verify(signature, digest, ec.ECDSA(utils.Prehashed(self._chosen_hash))) return True except CryptoError as e: logger.exception(str(e)) return False
def sign(self, data: bytes, algorithm: AlgType) -> bytes: """ Returns a signature of the provided data. :param data: Data to be signed. :type data: bytes :param algorithm: Hash algorithm used to sign the provided data. :type algorithm: AlgType :return: Signature of the provided data. :rtype: bytes """ if not self._private: raise InvalidKey("Cannot sign with a public key.") return self._private.sign(data, ec.ECDSA(_get_alg(algorithm)))
def create_signed_entry(entry, log_key, jws_header): """ Converts the unsigned manifest entry into the signed manifest format (divided jws) """ jws_data = {'header': {'uniqueId': entry['uniqueId']}, 'protected': jws_header, 'payload': jws_b64encode(json.dumps(entry).encode('ascii'))} tbs = jws_data['protected'] + '.' + jws_data['payload'] signature = log_key.sign(tbs.encode('ascii'), ec.ECDSA(hashes.SHA256())) r_int, s_int = crypto_utils.decode_dss_signature(signature) signature = int_to_bytes(r_int, 32) + int_to_bytes(s_int, 32) jws_data['signature'] = jws_b64encode(signature) return jws_data
def sign_callback( path, description, public_key, public_key_hint, hash_alg, data_to_sign, user_data, ): assert key_path.endswith(path) assert description == "PolicySigned" assert public_key == sign_key_public_pem assert public_key_hint == "Test key hint" assert hash_alg == lib.TPM2_ALG_SHA256 assert user_data == b"123456" # signing authority signs external to TPM (via openssl) to authorize usage of key (policy Signed) return sign_key.sign(data_to_sign, ec.ECDSA(hashes.SHA256()))
def validate_proof(proof: Proof, public_base58: str): """ Validate proof. :param proof: proof :param public_base58: public key base 58 used to create the proof :raises: IdentityInvalidProofError: if invalid proof signature IdentityInvalidProofError: if invalid proof """ public_ecdsa = KeysHelper.get_public_ECDSA_from_base58(public_base58) try: signature = base64.b64decode(proof.signature) public_ecdsa.verify(signature, proof.content, ec.ECDSA(hashes.SHA256())) except InvalidSignature as err: raise IdentityInvalidProofError('Invalid proof: invalid signature') from err except ValueError as err: raise IdentityInvalidProofError(f'Invalid proof: \'{err}\'') from err
def sign_data(data: bytes, private_key: ec.EllipticCurvePrivateKey, algorithm: ec.ECDSA = None) -> bytes: """ Sign data with the private key to ensure te receiving party that it is your's The other party needs the public key to ensure the signed data is from the expected source. The signature should be send with the data that is given. :param private_key: the private key to sign the data with :param data: data to sign :param algorithm: algorithm agreed upon with the receiving party :return: signature based on the data """ __assure_private_key(private_key) if not bool(algorithm): algorithm = ec.ECDSA(hashes.SHA256()) signed_data = private_key.sign(data, algorithm) return signed_data