def _verify(pubkey, sig, filehash, hashfunc): """ Do signature verification with the given public key """ if isinstance(pubkey, RSAPublicKey): pubkey.verify(sig, filehash, padding.PKCS1v15(), Prehashed(hashfunc)) elif isinstance(pubkey, EllipticCurvePublicKey): pubkey.verify(sig, filehash, ec.ECDSA(Prehashed(hashfunc)))
def test_prehashed_unsupported_in_signer_ctx(self, backend): private_key = DSA_KEY_1024.private_key(backend) with pytest.raises(TypeError), pytest.warns( CryptographyDeprecationWarning): private_key.signer( Prehashed(hashes.SHA1()) # type: ignore[arg-type] )
def test_prehashed_unsupported_in_verifier_ctx(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) private_key = ec.generate_private_key(ec.SECP256R1(), backend) public_key = private_key.public_key() with pytest.raises(TypeError), pytest.warns( CryptographyDeprecationWarning): public_key.verifier(b"0" * 64, ec.ECDSA(Prehashed(hashes.SHA1())))
def is_signed_by(self, channel: 'Output', ledger=None): if self.claim.unsigned_payload: pieces = [ Base58.decode(self.get_address(ledger)), self.claim.unsigned_payload, self.claim.signing_channel_hash[::-1] ] else: pieces = [ self.tx_ref.tx.inputs[0].txo_ref.hash, self.claim.signing_channel_hash, self.claim.to_message_bytes() ] digest = sha256(b''.join(pieces)) public_key = load_der_public_key( channel.claim.channel.public_key_bytes, default_backend()) hash = hashes.SHA256() signature = hexlify(self.claim.signature) r = int(signature[:int(len(signature) / 2)], 16) s = int(signature[int(len(signature) / 2):], 16) encoded_sig = ecdsa.util.sigencode_der(r, s, len(signature) * 4) try: public_key.verify(encoded_sig, digest, ec.ECDSA(Prehashed(hash))) return True except (ValueError, InvalidSignature): pass return False
def verify_signature(self, certificate_b64, signature_b64, digest_b64, algorithm): certificate = self._parse_certificate(certificate_b64) certificate = x509.load_pem_x509_certificate( certificate_b64, default_backend()) public_key = certificate.public_key() signature = b64decode(signature_b64) digest = b64decode(digest_b64) padding = PKCS1v15() if hasattr(algorithm, 'encode'): algorithm = algorithm.encode('utf8') algorithm = algorithm.decode("utf-8") hash_algorithm = self.algorithms[algorithm][1]() public_key.verify( signature, digest, padding, Prehashed(hash_algorithm) ) return True
def _ecc_static_length_signature(key, algorithm, digest): """Calculates an elliptic curve signature with a static length using pre-calculated hash. :param key: Elliptic curve private key :type key: cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey :param algorithm: Master algorithm to use :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param bytes digest: Pre-calculated hash digest :returns: Signature with required length :rtype: bytes """ pre_hashed_algorithm = ec.ECDSA(Prehashed(algorithm.signing_hash_type())) signature = b'' while len(signature) != algorithm.signature_len: _LOGGER.debug( 'Signature length %d is not desired length %d. Recalculating.', len(signature), algorithm.signature_len) signature = key.sign(digest, pre_hashed_algorithm) if len(signature) != algorithm.signature_len: # Most of the time, a signature of the wrong length can be fixed # by negating s in the signature relative to the group order. _LOGGER.debug( 'Signature length %d is not desired length %d. Negating s.', len(signature), algorithm.signature_len) r, s = decode_dss_signature(signature) s = _ECC_CURVE_PARAMETERS[ algorithm.signing_algorithm_info.name].order - s signature = encode_dss_signature(r, s) return signature
def getFileSignature(cls, filename: str, private_key: RSAPrivateKey) -> Optional[str]: """Creates the signature for the (hash of the) provided file, given a private key. :param filename: The file to be signed. :param private_key: The private key used for signing. :return: The signature if successful, 'None' otherwise. """ file_hash = cls.getFileHash(filename) if file_hash is None: return None try: file_hash_bytes = base64.b64decode(file_hash) signature_bytes = private_key.sign( file_hash_bytes, padding.PSS(mgf=padding.MGF1(cls.__hash_algorithm), salt_length=padding.PSS.MAX_LENGTH), Prehashed(cls.__hash_algorithm)) return base64.b64encode(signature_bytes).decode("utf-8") except: # Yes, we do really want this on _every_ exception that might occur. Logger.logException( "e", "Couldn't sign '{0}', no signature generated.".format( filename)) return None
def getHashSignature(cls, shash: str, private_key: RSAPrivateKey, err_info: Optional[str] = None) -> Optional[str]: """ Creates the signature for the provided hash, given a private key. :param shash: The provided string. :param private_key: The private key used for signing. :param err_info: Some optional extra info to be printed on error (for ex.: a filename the data came from). :return: The signature if successful, 'None' otherwise. """ try: hash_bytes = base64.b64decode(shash) signature_bytes = private_key.sign( hash_bytes, padding.PSS(mgf=padding.MGF1(cls.__hash_algorithm), salt_length=padding.PSS.MAX_LENGTH), Prehashed(cls.__hash_algorithm)) return base64.b64encode(signature_bytes).decode("utf-8") except: # Yes, we do really want this on _every_ exception that might occur. if err_info is None: err_info = "HASH:" + shash Logger.logException( "e", "Couldn't sign '{0}', no signature generated.".format( err_info)) return None
def test_prehashed_unsupported_in_verifier_ctx(self, backend): public_key = DSA_KEY_1024.private_key(backend).public_key() with pytest.raises(TypeError), \ pytest.warns(CryptographyDeprecationWarning): public_key.verifier( b"0" * 64, Prehashed(hashes.SHA1()) )
def is_signature_valid(encoded_signature, signature_digest, public_key_bytes): try: public_key = load_der_public_key(public_key_bytes, default_backend()) public_key.verify(encoded_signature, signature_digest, ec.ECDSA(Prehashed(hashes.SHA256()))) return True except (ValueError, InvalidSignature): pass return False
def sign(self, data, hash_context): if not isinstance(hash_context, hashes.HashContext): raise TypeError("hash_context must be an instance of hashes.HashContext.") hash_context.update(data) digest = hash_context.finalize() r, s = decode_dss_signature(self._key.sign(digest, Prehashed(SHA256HMAC160()))) # return long_to_bytes(r, 20) + long_to_bytes(s, 20) size = self.private_numbers.public_numbers.parameter_numbers.q.bit_length() // 8 return long_to_bytes(r, size) + long_to_bytes(s, size)
def sign(self, message: bytes) -> bytes: # NOTE: We use hashlib instead of cryptography's SHA256 because it's # much faster h = hashlib.sha256() h.update(message) return self._key.sign( h.digest(), padding.PSS(padding.MGF1(SHA256()), padding.PSS.MAX_LENGTH), Prehashed(SHA256()))
def test_prehashed_digest_mismatch(self, backend): private_key = DSA_KEY_1024.private_key(backend) message = b"one little message" h = hashes.Hash(hashes.SHA1(), backend) h.update(message) digest = h.finalize() prehashed_alg = Prehashed(hashes.SHA224()) with pytest.raises(ValueError): private_key.sign(digest, prehashed_alg)
def test_sign_prehashed_digest_mismatch(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) message = b"one little message" h = hashes.Hash(hashes.SHA1(), backend) h.update(message) data = h.finalize() algorithm = ec.ECDSA(Prehashed(hashes.SHA256())) private_key = ec.generate_private_key(ec.SECP256R1(), backend) with pytest.raises(ValueError): private_key.sign(data, algorithm)
def verify(self, signature): """Verifies the signature against the current cryptographic verifier state. :param bytes signature: The signature to verify """ prehashed_digest = self._hasher.finalize() self.key.verify(signature=signature, data=prehashed_digest, signature_algorithm=ec.ECDSA( Prehashed(self.algorithm.signing_hash_type())))
def test_prehashed_sign(self, backend): private_key = DSA_KEY_1024.private_key(backend) message = b"one little message" h = hashes.Hash(hashes.SHA1(), backend) h.update(message) digest = h.finalize() prehashed_alg = Prehashed(hashes.SHA1()) signature = private_key.sign(digest, prehashed_alg) public_key = private_key.public_key() public_key.verify(signature, message, hashes.SHA1())
def is_signature_valid(encoded_signature, signature_digest, public_key_bytes) -> bool: try: public_key = load_der_public_key(public_key_bytes, default_backend()) public_key.verify(encoded_signature, signature_digest, ec.ECDSA(Prehashed(hashes.SHA256()))) return True except (ValueError, InvalidSignature): logger.exception('Signature validation failed') return False
def test_verify_prehashed(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) message = b"one little message" algorithm = ec.ECDSA(hashes.SHA1()) private_key = ec.generate_private_key(ec.SECP256R1(), backend) signature = private_key.sign(message, algorithm) h = hashes.Hash(hashes.SHA1(), backend) h.update(message) data = h.finalize() public_key = private_key.public_key() public_key.verify(signature, data, ec.ECDSA(Prehashed(hashes.SHA1())))
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 test_verify_prehashed_digest_mismatch(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) message = b"one little message" private_key = ec.generate_private_key(ec.SECP256R1(), backend) h = hashes.Hash(hashes.SHA1(), backend) h.update(message) data = h.finalize() public_key = private_key.public_key() with pytest.raises(ValueError): public_key.verify(b"\x00" * 32, data, ec.ECDSA(Prehashed(hashes.SHA256())))
def alternative_evmctl_check(file_path, pubkey): # In RHEL7, evmctl is too old, so we won't be able to run the # evmctl check ima_sig = bytearray(xattr.getxattr(file_path, 'user.ima')) if ima_sig[0] != 3: raise Exception("IMA signature has wrong prefix (%s)" % ima_sig[0]) if ima_sig[1] != 2: raise Exception("IMA signature has wrong version (%s)" % ima_sig[1]) algo_id = ima_sig[2] if algo_id == 7: # SHA224 hasher = hashlib.sha224() crypto_algo = crypto_hashes.SHA224() elif algo_id == 4: # SHA256 hasher = hashlib.sha256() crypto_algo = crypto_hashes.SHA256() elif algo_id == 5: # SHA384 hasher = hashlib.sha384() crypto_algo = crypto_hashes.SHA384() elif algo_id == 6: # SHA512 hasher = hashlib.sha512() crypto_algo = crypto_hashes.SHA512() else: raise Exception("IMA signature has invalid algo: %d" % algo_id) crypto_algo = Prehashed(crypto_algo) if sys.version_info.major == 3: # X962 is only supported on Cryptography 2.5+ # We are a bit lazy and just check for py3 instead of checking this more carefully # Check the Key ID key_id = ima_sig[3:7] keybytes = pubkey.public_bytes( crypto_serialization.Encoding.X962, crypto_serialization.PublicFormat.UncompressedPoint, ) keybytes_digester = Hash(SHA1()) keybytes_digester.update(keybytes) keybytes_digest = keybytes_digester.finalize() correct_keyid = keybytes_digest[-4:] if correct_keyid != key_id: raise Exception("IMA signature has invalid key ID: %s != %s" % (correct_keyid, key_id)) # Check the signature itself (sig_size,) = struct.unpack('>H', ima_sig[7:9]) sig = ima_sig[9:] if len(sig) != sig_size: raise Exception("IMA signature size invalid: %d != %d" % (len(sig), sig_size)) with open(file_path, 'rb') as f: hasher.update(f.read()) file_digest = hasher.digest() pubkey.verify( bytes(sig), bytes(file_digest), crypto_ec.ECDSA(crypto_algo), )
def verify(self, signature, data, hash_context): if not isinstance(hash_context, hashes.HashContext): raise TypeError("hash_context must be an instance of hashes.HashContext.") size = self.public_numbers.parameter_numbers.q.bit_length() // 8 r, s = (bytes_to_long(value) for value in read_content(signature, '{0}s{0}s'.format(size))) # r, s = (bytes_to_long(value) for value in read_content(signature, '20s20s')) hash_context.update(data) digest = hash_context.finalize() try: self._key.verify(encode_dss_signature(r, s), digest, Prehashed(SHA256HMAC160())) except InvalidSignature: raise ValueError("invalid signature")
def verify(self, message: bytes, signature: bytes) -> bool: # NOTE: We use hashlib instead of cryptography's SHA256 because it's # much faster h = hashlib.sha256() h.update(message) try: self._key.verify( signature, h.digest(), padding.PSS(padding.MGF1(SHA256()), padding.PSS.MAX_LENGTH), Prehashed(SHA256())) return True except InvalidSignature: return False
def create_signature(self, private_key, digest_b64, algorithm=( "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")): data = b64decode(digest_b64) padding = PKCS1v15() algorithm = self._encode_string(algorithm) algorithm = algorithm.decode("utf-8") hash_algorithm = self.algorithms[algorithm][1]() signature = private_key.sign(data, padding, Prehashed(hash_algorithm)) return signature
def pritunl_sign(private_key, *args): '''RSA sign content provided in args''' data = '&'.join(args).encode() data_hash = sha512(data).digest() user_privkey = serialization.load_pem_private_key(private_key.encode(), password=None) rsa_sig = user_privkey.sign( data_hash, padding.PSS(mgf=padding.MGF1(hashes.SHA512()), salt_length=padding.PSS.MAX_LENGTH), Prehashed(hashes.SHA512())) sig64 = b64encode(rsa_sig).decode('ascii') return sig64
def is_signature_valid(signature, digest, public_key_bytes): signature = cdata_to_der(deserialize_compact(signature)) public_key = cPublicKey(public_key_bytes) is_valid = public_key.verify(signature, digest, None) if not is_valid: # try old way # ytsync signed claims don't seem to validate with coincurve try: pk = ec.EllipticCurvePublicKey.from_encoded_point( ec.SECP256K1(), public_key_bytes) pk.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256()))) return True except (ValueError, InvalidSignature): pass return is_valid
def verify_sig(self, digest, signature): public_key = serialization.load_pem_private_key( self.private_key.encode(), password=None, backend=default_backend(), ).public_key() public_key.verify( signature, digest, padding.PSS( mgf=padding.MGF1(hashes.SHA512()), salt_length=padding.PSS.MAX_LENGTH, ), Prehashed(hashes.SHA512()), )
def getFileSignature(cls, filename: str, private_key: RSAPrivateKey) -> Optional[str]: file_hash = cls.getFileHash(filename) if file_hash is None: return None try: file_hash_bytes = base64.b64decode(file_hash) signature_bytes = private_key.sign( file_hash_bytes, padding.PSS(mgf=padding.MGF1(cls.__hash_algorithm), salt_length=padding.PSS.MAX_LENGTH), Prehashed(cls.__hash_algorithm)) return base64.b64encode(signature_bytes).decode("utf-8") except: # Yes, we do really want this on _every_ exception that might occur. Logger.logException( "e", "Couldn't sign '{0}', no signature generated.".format( filename)) return None
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 _verifyHash(self, shash: str, signature: str, err_info: Optional[str] = None) -> bool: if self._public_key is None: return False try: signature_bytes = base64.b64decode(signature) hash_bytes = base64.b64decode(shash) self._public_key.verify( signature_bytes, hash_bytes, padding.PSS(mgf = padding.MGF1(TrustBasics.getHashAlgorithm()), salt_length = padding.PSS.MAX_LENGTH), Prehashed(TrustBasics.getHashAlgorithm()) ) return True except: # Yes, we do really want this on _every_ exception that might occur. if err_info is None: err_info = "HASH:" + shash self._violation_handler("Couldn't verify '{0}' with supplied signature.".format(err_info)) return False