def verify_compact_verbose(self, jws=None, keys=None, allow_none=False,
                               sigalg=None):
        """
        Verify a JWT signature and return dict with validation results

        :param jws: A signed JSON Web Token
        :param keys: A list of keys that can possibly be used to verify the
            signature
        :param allow_none: If signature algorithm 'none' is allowed
        :param sigalg: Expected sigalg
        :return: Dictionary with 2 keys 'msg' required, 'key' optional.
            The value of 'msg' is the unpacked and verified message.
            The value of 'key' is the key used to verify the message
        """
        if jws:
            jwt = JWSig().unpack(jws)
            if len(jwt) != 3:
                raise WrongNumberOfParts(len(jwt))

            self.jwt = jwt
        elif not self.jwt:
            raise ValueError('Missing singed JWT')
        else:
            jwt = self.jwt

        try:
            _alg = jwt.headers["alg"]
        except KeyError:
            _alg = None
        else:
            if _alg is None or _alg.lower() == "none":
                if allow_none:
                    self.msg = jwt.payload()
                    return {'msg': self.msg}
                else:
                    raise SignerAlgError("none not allowed")

        if "alg" in self and self['alg'] and _alg:
            if isinstance(self['alg'], list):
                if _alg not in self["alg"] :
                    raise SignerAlgError(
                        "Wrong signing algorithm, expected {} got {}".format(
                            self['alg'], _alg))
            elif _alg != self['alg']:
                raise SignerAlgError(
                    "Wrong signing algorithm, expected {} got {}".format(
                        self['alg'], _alg))

        if sigalg and sigalg != _alg:
            raise SignerAlgError("Expected {0} got {1}".format(
                sigalg, jwt.headers["alg"]))

        self["alg"] = _alg

        if keys:
            _keys = self.pick_keys(keys)
        else:
            _keys = self.pick_keys(self._get_keys())

        if not _keys:
            if "kid" in self:
                raise NoSuitableSigningKeys(
                    "No key with kid: %s" % (self["kid"]))
            elif "kid" in self.jwt.headers:
                raise NoSuitableSigningKeys(
                    "No key with kid: %s" % (self.jwt.headers["kid"]))
            else:
                raise NoSuitableSigningKeys("No key for algorithm: %s" % _alg)

        verifier = SIGNER_ALGS[_alg]

        for key in _keys:
            if isinstance(key, AsymmetricKey):
                _key = key.public_key()
            else:
                _key = key.key

            try:
                if not verifier.verify(jwt.sign_input(), jwt.signature(), _key):
                    continue
            except (BadSignature, IndexError):
                pass
            except (ValueError, TypeError) as err:
                logger.warning('Exception "{}" caught'.format(err))
            else:
                logger.debug(
                    "Verified message using key with kid=%s" % key.kid)
                self.msg = jwt.payload()
                self.key = key
                return {'msg': self.msg, 'key': key}

        raise BadSignature()
Verify a JWT signature and return dict with validation results

        :param jws: A signed JSON Web Token
        :param keys: A list of keys that can possibly be used to verify the
            signature
        :param allow_none: If signature algorithm 'none' is allowed
        :param sigalg: Expected sigalg
        :return: Dictionary with 2 keys 'msg' required, 'key' optional.
            The value of 'msg' is the unpacked and verified message.
            The value of 'key' is the key used to verify the message