def verify(self, message: bytes, verifying_key: UmbralPublicKey, is_prehashed: bool = False) -> bool: """ Verifies that a message's signature was valid. :param message: The message to verify :param verifying_key: UmbralPublicKey of the signer :param is_prehashed: True if the message has been prehashed previously :return: True if valid, False if invalid """ cryptography_pub_key = verifying_key.to_cryptography_pubkey() if is_prehashed: signature_algorithm = ECDSA(utils.Prehashed(self.hash_algorithm())) else: signature_algorithm = ECDSA(self.hash_algorithm()) # TODO: Raise error instead of returning boolean try: cryptography_pub_key.verify( signature=self._der_encoded_bytes(), data=message, signature_algorithm=signature_algorithm) except InvalidSignature: return False return True
def get_ec2_sig_alg( alg_id: COSEAlgorithmIdentifier) -> EllipticCurveSignatureAlgorithm: """Turn an "ECDSA" COSE algorithm identifier into a corresponding signature algorithm """ if alg_id == COSEAlgorithmIdentifier.ECDSA_SHA_256: return ECDSA(SHA256()) if alg_id == COSEAlgorithmIdentifier.ECDSA_SHA_512: return ECDSA(SHA512()) raise UnsupportedAlgorithm(f"Unrecognized EC2 signature alg {alg_id}")
def verify_renewable_cert_sig(renewable_cert): """ Verifies the signature of a `.storage.RenewableCert` object. :param `.storage.RenewableCert` renewable_cert: cert to verify :raises errors.Error: If signature verification fails. """ try: with open(renewable_cert.chain, 'rb') as chain_file: # type: IO[bytes] chain = x509.load_pem_x509_certificate(chain_file.read(), default_backend()) with open(renewable_cert.cert, 'rb') as cert_file: # type: IO[bytes] cert = x509.load_pem_x509_certificate(cert_file.read(), default_backend()) pk = chain.public_key() with warnings.catch_warnings(): warnings.simplefilter("ignore") if isinstance(pk, RSAPublicKey): # https://github.com/python/typeshed/blob/master/third_party/2/cryptography/hazmat/primitives/asymmetric/rsa.pyi verifier = pk.verifier( # type: ignore cert.signature, PKCS1v15(), cert.signature_hash_algorithm) verifier.update(cert.tbs_certificate_bytes) verifier.verify() elif isinstance(pk, EllipticCurvePublicKey): verifier = pk.verifier(cert.signature, ECDSA(cert.signature_hash_algorithm)) verifier.update(cert.tbs_certificate_bytes) verifier.verify() else: raise errors.Error("Unsupported public key type") except (IOError, ValueError, InvalidSignature) as e: error_str = "verifying the signature of the cert located at {0} has failed. \ Details: {1}".format(renewable_cert.cert, e) logger.exception(error_str) raise errors.Error(error_str)
def publish(event, context): """Publish PyPI vulnerability.""" del context data = json.loads(base64.b64decode(event['data'])) vulnerability = osv.parse_vulnerability_from_dict(data) key_data = _get_private_key() private_key = serialization.load_pem_private_key( data=key_data['key'].encode(), password=None) request = json.dumps([{ 'id': vulnerability.id, 'project': vulnerability.package.name, 'versions': list(vulnerability.affects.versions), 'link': f'https://osv.dev/vulnerability/{vulnerability.id}', 'aliases': list(vulnerability.aliases), }]).encode() signature = private_key.sign(data=request, signature_algorithm=ECDSA(algorithm=SHA256())) headers = { 'VULN-PUBLIC-KEY-IDENTIFIER': key_data['id'], 'VULN-PUBLIC-KEY-SIGNATURE': base64.b64encode(signature).decode(), } print(f'Posting {vulnerability.id} to PyPI:', request.decode()) response = requests.post(_ENDPOINT, data=request, headers=headers) response.raise_for_status()
def verify_ec2_public_key(credential_public_key: EC2CredentialPublicKey, signature: bytes, data: bytes) -> None: """Verify the a signature over data using an `EC2CredentialPublicKey`. Args: credential_public_key (EC2CredentialPublicKey): The credential public key to use for verification. signature (bytes): The signature to verify. data (bytes): The data over which to compute the signature. Raises: VerificationError: If the provided signature is not correct. UnimplementedError: If the logic to verify using the given type of key is not implemented. """ public_key = cast(EC2PublicKey, cryptography_public_key(credential_public_key)) if credential_public_key.alg is None: raise VerificationError('alg must not be None') signature_algorithm = ECDSA(ec2_hash_algorithm(credential_public_key.alg)) try: public_key.verify(signature, data, signature_algorithm) except cryptography.exceptions.InvalidSignature: raise VerificationError('EC2 verification failure')
def sign_message(private_key, data): signature = private_key.sign(data, ECDSA(SHA512())) public_key = encode_public_key(private_key.public_key()) header = {"key": b64encode(public_key).decode(), 'sig': b64encode(signature).decode()} return b'S' + format_header(header) + data
def _validate_raw(signature: bytes, signed_data: bytes, cert: x509.Certificate, signature_algorithm: cms.SignedDigestAlgorithm, md_algorithm: str, prehashed=False): try: md_algorithm = signature_algorithm.hash_algo.upper() except (ValueError, AttributeError): pass verify_md = _get_pyca_cryptography_hash(md_algorithm, prehashed=prehashed) pub_key = serialization.load_der_public_key(cert.public_key.dump()) sig_algo = signature_algorithm.signature_algo if sig_algo == 'rsassa_pkcs1v15': assert isinstance(pub_key, RSAPublicKey) pub_key.verify(signature, signed_data, padding.PKCS1v15(), verify_md) elif sig_algo == 'rsassa_pss': assert isinstance(pub_key, RSAPublicKey) pss_padding, hash_algo = _process_pss_params( signature_algorithm['parameters'], md_algorithm, prehashed=prehashed) pub_key.verify(signature, signed_data, pss_padding, hash_algo) elif sig_algo == 'ecdsa': assert isinstance(pub_key, EllipticCurvePublicKey) pub_key.verify(signature, signed_data, ECDSA(verify_md)) else: # pragma: nocover raise SignatureValidationError( f"Signature mechanism {sig_algo} is not supported.")
def test_verify_ec2(crv: EC2Curve.Value, alg: COSEAlgorithmIdentifier.Value, data: bytes): private_key = generate_ec2_private_key(crv) clen = curve_coordinate_byte_length(crv) public_key = private_key.public_key() public_numbers = public_key.public_numbers() ec2_public_key = EC2CredentialPublicKey( kty=COSEKeyType.Value.EC2, crv=crv, alg=alg, x=public_numbers.x.to_bytes(clen, 'big'), y=public_numbers.y.to_bytes(clen, 'big'), ) signature_algorithm = ECDSA(ec2_hash_algorithm(alg)) signature = private_key.sign(data, signature_algorithm) verify(ec2_public_key, signature, data) errors = single_byte_errors(signature) for error in errors: with pytest.raises(VerificationError): verify(ec2_public_key, error, data)
def verify_signed_payload(public_key, signature, payload, signature_hash_algorithm): """Check the signature of a payload. :param RSAPublicKey/EllipticCurvePublicKey public_key: the public_key to check signature :param bytes signature: the signature bytes :param bytes payload: the payload bytes :param cryptography.hazmat.primitives.hashes.HashAlgorithm signature_hash_algorithm: algorithm used to hash the payload :raises InvalidSignature: If signature verification fails. :raises errors.Error: If public key type is not supported """ with warnings.catch_warnings(): warnings.simplefilter("ignore") if isinstance(public_key, RSAPublicKey): # https://github.com/python/typeshed/blob/master/third_party/2/cryptography/hazmat/primitives/asymmetric/rsa.pyi verifier = public_key.verifier( # type: ignore signature, PKCS1v15(), signature_hash_algorithm) verifier.update(payload) verifier.verify() elif isinstance(public_key, EllipticCurvePublicKey): verifier = public_key.verifier(signature, ECDSA(signature_hash_algorithm)) verifier.update(payload) verifier.verify() else: raise errors.Error("Unsupported public key type")
def webauthnGet(self, resp, raw_id, authData, signature, user_handle, client_data_hash): logging.debug('===assertion===') if authData: logging.debug('authData') if authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest(): logging.debug('\trpidHash ' + str(authData[:32].hex())) flags = int.from_bytes(authData[32:33], 'big') logging.debug(f'\tflags {bin(flags)}, {bin(flags & 0b0100_0000)}, {bin(flags & 0b1000_0000)}') logging.debug('\tsigCount ' + str(int.from_bytes(authData[33:37], 'big'))) with open(f"./keys/{base64.urlsafe_b64encode(raw_id).decode()}.cbor") as f: public_key = cbor.loads(base64.b64decode(f.readline().encode())) if public_key[3] == -7: # TODO: 他のアルゴリズムへの対応 verification_data = authData + client_data_hash x = int(codecs.encode(public_key[-2], 'hex'), 16) y = int(codecs.encode(public_key[-3], 'hex'), 16) credential_public_key = EllipticCurvePublicNumbers(x, y, SECP256R1()).public_key(backend=default_backend()) try: credential_public_key.verify(signature, verification_data, ECDSA(SHA256())) resp.media = {'status': 'ok'} logging.info('[success] navigator.credentials.get') except InvalidSignature as e: logging.info(f'InvalidSignature {e}') resp.media = {'status': 'ng'} else: logging.info('not support type') resp.media = {'status': 'ng'} else: logging.info('not match RPID') logging.debug(f'{authData[:32].hex()}, {hashlib.sha256(rpid_host.encode()).hexdigest()} [{authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest()}]') resp.media = {'status': 'ng'} else: logging.info('not find authData') resp.media = {'status': 'ng'}
def _verify_response(issuer_cert, ocsp_response): pubkey = issuer_cert.public_key() try: if isinstance(pubkey, RSAPublicKey): pubkey.verify( ocsp_response.signature, ocsp_response.tbs_response_bytes, PKCS1v15(), ocsp_response.signature_hash_algorithm, ) elif isinstance(pubkey, DSAPublicKey): pubkey.verify( ocsp_response.signature, ocsp_response.tbs_response_bytes, ocsp_response.signature_hash_algorithm, ) elif isinstance(pubkey, EllipticCurvePublicKey): pubkey.verify( ocsp_response.signature, ocsp_response.tbs_response_bytes, ECDSA(ocsp_response.signature_hash_algorithm), ) else: pubkey.verify(ocsp_response.signature, ocsp_response.tbs_response_bytes) except InvalidSignature: raise ConnectionError("failed to valid ocsp response")
def verify(public_key: KEY_PUBLIC_TYPES, blocks: Generator[bytes, None, None], signature: bytes) -> Tuple[int, bool]: count = 0 try: chosen_hash = hashes.SHA256() hasher = hashes.Hash(chosen_hash) count = 0 for block in blocks: count += len(block) hasher.update(block) digest = hasher.finalize() if isinstance(public_key, RSAPublicKey): public_key.verify( signature, digest, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), utils.Prehashed(chosen_hash)) elif isinstance(public_key, Ed25519PublicKey): public_key.verify(signature, digest) elif isinstance(public_key, EllipticCurvePublicKey): public_key.verify(signature, digest, ECDSA(utils.Prehashed(chosen_hash))) else: raise InternalException("Unknown key type") return count, True except InvalidSignature: return count, False
def ecdsa_sign(curve: Curve, secret_bn, prehashed_message: bytes, hash_algorithm) -> Tuple[int, int]: signature_algorithm = ECDSA(utils.Prehashed(hash_algorithm)) private_key = bn_to_privkey(curve, secret_bn) signature_der_bytes = private_key.sign(prehashed_message, signature_algorithm) r_int, s_int = utils.decode_dss_signature(signature_der_bytes) return r_int, s_int
def verify_signature_ecc(signature, key, halg, data): sig = signature.signature rbytes = buffer_to_bytes(sig.ecdsa.signatureR) r = int.from_bytes(rbytes, 'big') sbytes = buffer_to_bytes(sig.ecdsa.signatureS) s = int.from_bytes(sbytes, 'big') dersig = encode_dss_signature(r, s) key.verify(dersig, data, ECDSA(halg()))
def _verify_signature(self, request, signature): """Verify signature.""" public_key = serialization.load_pem_public_key(data=_FAKE_PUB_KEY) public_key.verify( signature=base64.b64decode(signature), data=request, signature_algorithm=ECDSA(algorithm=SHA256()), )
def file_hash(f): ctx = SHA512() hasher = Hash(ctx, default_backend()) while True: data = f.read(1024) if not data: break hasher.update(data) digest = hasher.finalize() alg = ECDSA(Prehashed(ctx)) return digest, alg
def ecdsa_with_hash(hsh: str) -> ECDSA: """ Utility function for cryptography EllipticCurveSignatureAlgorithm instance :param k: str hash name :return: ECDSA instance """ return ECDSA(engine_hashes(hsh))
def test_credentials_backend_request_success(): backend = CredentialsBackend(SuccessCredentialsRegistrar()) challenge = b'challenge' credential_id = b'credential-id' auth_data = authenticator_data( TEST_RP_ID_HASH, (AuthenticatorDataFlag.UP.value | AuthenticatorDataFlag.AT.value | AuthenticatorDataFlag.ED.value), b'\x00' * 4, attested_credential_data( b'z' * 16, len(credential_id), credential_id, cbor2.dumps({ -3: TEST_CREDENTIAL_PUBLIC_KEY.y, -2: TEST_CREDENTIAL_PUBLIC_KEY.x, -1: TEST_CREDENTIAL_PUBLIC_KEY.crv.value, 1: TEST_CREDENTIAL_PUBLIC_KEY.kty.value, 3: TEST_CREDENTIAL_PUBLIC_KEY.alg.value, }), ), cbor2.dumps({ 'appid': True, })) client_data_JSON = json_bytes({ 'type': 'webauthn.get', 'challenge': base64s(challenge), 'origin': TEST_RP_ORIGIN, }) signature_algorithm = ECDSA(ec2_hash_algorithm(TEST_COSE_ALG)) signature = TEST_CRYPTOGRAPHY_PRIVATE_KEY.sign( auth_data + hashlib.sha256(client_data_JSON).digest(), signature_algorithm, ) public_key_credential = PublicKeyCredential( id=base64s(credential_id), type='credential-type', raw_id=credential_id, response=AuthenticatorAssertionResponse( client_data_JSON=client_data_JSON, authenticator_data=auth_data, signature=signature, )) expected_challenge = challenge backend.handle_credential_assertion( credential=public_key_credential, user=TEST_USER, rp=TEST_RP, expected_challenge=expected_challenge, expected_origin=TEST_RP_ORIGIN, )
def __call__(self, message: bytes, is_prehashed: bool = False) -> Signature: """ Signs the message with this instance's private key. :param message: Message to hash and sign :param is_prehashed: True if the message has been prehashed previously :return: signature """ if is_prehashed: signature_algorithm = ECDSA(utils.Prehashed(self.hash_algorithm())) else: signature_algorithm = ECDSA(self.hash_algorithm()) signature_der_bytes = self.__cryptography_private_key.sign( message, signature_algorithm) return Signature.from_bytes(signature_der_bytes, der_encoded=True, curve=self.curve)
def verify(self, msg, key, sig): try: der_sig = raw_to_der_signature(sig, key.curve) except ValueError: return False try: key.verify(der_sig, msg, ECDSA(self.hash_alg())) return True except InvalidSignature: return False
def __call__(self, message: bytes) -> Signature: """ Signs the message with this instance's private key. :param message: Message to hash and sign :return: signature """ signature_der_bytes = self.__cryptography_private_key.sign( message, ECDSA(_BLAKE2B)) return Signature.from_bytes(signature_der_bytes, der_encoded=True, curve=self._curve)
def ecdsa_verify(curve: Curve, sig_r: int, sig_s: int, public_point, prehashed_message: bytes, hash_algorithm) -> bool: signature_algorithm = ECDSA(utils.Prehashed(hash_algorithm)) public_key = point_to_pubkey(curve, public_point) signature_der_bytes = utils.encode_dss_signature(sig_r, sig_s) try: public_key.verify(signature=signature_der_bytes, data=prehashed_message, signature_algorithm=signature_algorithm) except InvalidSignature: return False return True
def attest_android_key( att_stmt: AndroidKeyAttestationStatement, att_obj: AttestationObject, auth_data: bytes, client_data_hash: bytes) -> Tuple[AttestationType, TrustedPath]: if len(att_stmt.x5c) == 0: raise ValidationError('Must have at least 1 X509 certificate') credential_certificate = cryptography.x509.load_pem_x509_certificate( att_stmt.x5c[0], default_backend()) cred_cert_pk = credential_certificate.public_key() assert att_stmt.alg is not None alg_name = att_stmt.alg.name alg_to_hash = { 'ES256': SHA256, 'ES384': SHA384, 'ES512': SHA512, } hash_algorithm = None if alg_name in alg_to_hash: hash_algorithm = ECDSA(alg_to_hash[alg_name]()) elif alg_name != 'EDDSA': raise ValidationError( 'Unsupported hashing algorithm {}'.format(alg_name)) verification_data = auth_data + client_data_hash try: if hash_algorithm is not None: cred_cert_pk.verify(att_stmt.sig, verification_data, hash_algorithm) else: cred_cert_pk.verify(att_stmt.sig, verification_data) except cryptography.exceptions.InvalidSignature: raise VerificationError( 'Android Key verification failed: invalid signature') assert att_obj.auth_data is not None assert att_obj.auth_data.attested_credential_data is not None cpk = cryptography_public_key( att_obj.auth_data.attested_credential_data.credential_public_key) if cpk != cred_cert_pk: raise ValidationError( ('Certificate public key in attestation statement must match the ' 'provided credential public key')) return AttestationType.UNCERTAIN, [credential_certificate]
def verify(self, msg, key, sig): key_size = key.curve.key_size length = (key_size + 7) // 8 if len(sig) != 2 * length: return False r = decode_int(sig[:length]) s = decode_int(sig[length:]) der_sig = encode_dss_signature(r, s) try: key.verify(der_sig, msg, ECDSA(self.hash_alg())) return True except InvalidSignature: return False
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() # TODO: Raise error instead of returning boolean try: cryptography_pub_key.verify(self._der_encoded_bytes(), message, ECDSA(_BLAKE2B)) except InvalidSignature: return False return True
def _check_signature(self, payload, public_key, signature): try: loaded_public_key = serialization.load_pem_public_key( data=public_key.encode("utf-8"), backend=default_backend()) loaded_public_key.verify( signature=base64.b64decode(signature), data=payload.encode("utf-8"), # This validates the ECDSA and SHA256 part signature_algorithm=ECDSA(algorithm=SHA256()), ) except InvalidSignature as exc: raise InvalidTokenLeakRequest("Invalid signature", "invalid_signature") from exc except Exception as exc: # Maybe the key is not a valid ECDSA key, maybe the data is not properly # padded, etc. So many things can go wrong... raise InvalidTokenLeakRequest("Invalid cryptographic values", "invalid_crypto") from exc
def validate_raw(signature: bytes, signed_data: bytes, cert: x509.Certificate, signature_algorithm: cms.SignedDigestAlgorithm, md_algorithm: str, prehashed=False, weak_hash_algorithms=DEFAULT_WEAK_HASH_ALGORITHMS): """ Validate a raw signature. Internal API. """ try: sig_md_algorithm = signature_algorithm.hash_algo except (ValueError, AttributeError): sig_md_algorithm = None if sig_md_algorithm is not None: if sig_md_algorithm in weak_hash_algorithms: raise WeakHashAlgorithmError(md_algorithm) md_algorithm = sig_md_algorithm.upper() verify_md = get_pyca_cryptography_hash(md_algorithm, prehashed=prehashed) pub_key = serialization.load_der_public_key( cert.public_key.dump() ) sig_algo = signature_algorithm.signature_algo if sig_algo == 'rsassa_pkcs1v15': assert isinstance(pub_key, RSAPublicKey) pub_key.verify(signature, signed_data, padding.PKCS1v15(), verify_md) elif sig_algo == 'rsassa_pss': assert isinstance(pub_key, RSAPublicKey) pss_padding, hash_algo = process_pss_params( signature_algorithm['parameters'], md_algorithm, prehashed=prehashed ) pub_key.verify(signature, signed_data, pss_padding, hash_algo) elif sig_algo == 'dsa': assert isinstance(pub_key, DSAPublicKey) pub_key.verify(signature, signed_data, verify_md) elif sig_algo == 'ecdsa': assert isinstance(pub_key, EllipticCurvePublicKey) pub_key.verify(signature, signed_data, ECDSA(verify_md)) else: # pragma: nocover raise NotImplementedError( f"Signature mechanism {sig_algo} is not supported." )
def verify_signature(sig, data, pubkey): from cryptography.hazmat.primitives.hashes import SHA256 from cryptography.hazmat.primitives.asymmetric.ec import ECDSA from pyasn1.codec.der.encoder import encode from pyasn1.type.univ import Integer, SequenceOf if len(sig) != 64: return False seq = SequenceOf(componentType=Integer()) seq[0] = Util.long_from_bytes(sig[:32]) seq[1] = Util.long_from_bytes(sig[32:]) try: pubkey.verify(encode(seq), data, ECDSA(SHA256())) except: return False return True
def sign(private_key: KEY_PRIVATE_TYPES, blocks: Generator[bytes, None, None]) -> Tuple[int, bytes]: chosen_hash = hashes.SHA256() hasher = hashes.Hash(chosen_hash) count = 0 for block in blocks: count += len(block) hasher.update(block) digest = hasher.finalize() if isinstance(private_key, RSAPrivateKey): sig = private_key.sign( digest, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), utils.Prehashed(chosen_hash)) elif isinstance(private_key, Ed25519PrivateKey): sig = private_key.sign(digest) elif isinstance(private_key, EllipticCurvePrivateKey): sig = private_key.sign(digest, ECDSA(utils.Prehashed(chosen_hash))) else: raise InternalException("Unknown key type") return count, sig
def verify_signed_payload( public_key: Union[DSAPublicKey, 'Ed25519PublicKey', 'Ed448PublicKey', EllipticCurvePublicKey, RSAPublicKey], signature: bytes, payload: bytes, signature_hash_algorithm: hashes.HashAlgorithm) -> None: """Check the signature of a payload. :param RSAPublicKey/EllipticCurvePublicKey public_key: the public_key to check signature :param bytes signature: the signature bytes :param bytes payload: the payload bytes :param hashes.HashAlgorithm signature_hash_algorithm: algorithm used to hash the payload :raises InvalidSignature: If signature verification fails. :raises errors.Error: If public key type is not supported """ if isinstance(public_key, RSAPublicKey): public_key.verify(signature, payload, PKCS1v15(), signature_hash_algorithm) elif isinstance(public_key, EllipticCurvePublicKey): public_key.verify(signature, payload, ECDSA(signature_hash_algorithm)) else: raise errors.Error("Unsupported public key type.")