@param array                     $complete_header The complete header
@param \Jose\Object\JWKInterface $key

@return \Jose\Algorithm\SignatureAlgorithmInterface
352372
private function getSignatureAlgorithm(array $complete_header, JWKInterface $key)
    {
        $this->log(LogLevel::DEBUG, 'Trying to find the algorithm used to sign');
        Assertion::keyExists($complete_header, 'alg', 'No "alg" parameter set in the header.');

        $this->log(LogLevel::DEBUG, 'The algorithm is {alg}', ['alg' => $complete_header['alg']]);

        Assertion::false(
            $key->has('alg') && $key->get('alg') !== $complete_header['alg'],
            sprintf('The algorithm "%s" is not allowed with this key.', $complete_header['alg'])
        );

        $signature_algorithm = $this->getJWAManager()->getAlgorithm($complete_header['alg']);
        Assertion::isInstanceOf($signature_algorithm, SignatureAlgorithmInterface::class, sprintf('The algorithm "%s" is not supported.', $complete_header['alg']));

        $this->log(LogLevel::DEBUG, 'The algorithm {alg} is supported', ['alg' => $complete_header['alg'], 'handler' => $signature_algorithm]);

        return $signature_algorithm;
    }
216442
private static function createJWSAndSign($payload, JWKInterface $signature_key, array $protected_headers = [], $headers = [])
    {
        $jws = self::createJWS($payload);

        $jws = $jws->addSignatureInformation($signature_key, $protected_headers, $headers);

        $complete_headers = array_merge($protected_headers, $headers);
        Assertion::keyExists($complete_headers, 'alg', 'No "alg" parameter set in the header');
        $signer = Signer::createSigner([$complete_headers['alg']]);
        $signer->sign($jws);

        return $jws;
    }
283673
private function getContentEncryptionAlgorithm(array $complete_headers)
    {
        $this->log(LogLevel::DEBUG, 'Trying to find content encryption algorithm');
        $content_encryption_algorithm = $this->getJWAManager()->getAlgorithm($complete_headers['enc']);
        if (!$content_encryption_algorithm instanceof ContentEncryptionAlgorithmInterface) {
            $exception = new \InvalidArgumentException(sprintf('The key encryption algorithm "%s" is not supported or does not implement ContentEncryptionInterface.', $complete_headers['enc']));
            $this->log(LogLevel::ERROR, 'The key encryption algorithm {alg} is not supported or does not implement ContentEncryptionInterface.', ['alg' => $complete_headers['enc'], 'exception' => $exception]);
            throw $exception;
        }

        $this->log(LogLevel::DEBUG, 'Content encryption algorithm {algorithm} found', ['algorithm' => $complete_headers['enc'], 'service' > $content_encryption_algorithm]);

        return $content_encryption_algorithm;
    }
335753
public function decode($token, $key = null)
    {
        $key = empty($key) ? $this->key : $key;

        $timestamp = empty($this->timestamp) ? time() : $this->timestamp;

        $segments = explode('.', $token);
        $segments = array_map('trim', $segments);

        if (count($segments) == 3) {
            list($headers, $payload, $signature) = $segments;

            // Base64 decode headers
            if (false === ($headers = Base64::decode($headers))) {
                $this->errors[] = 'Invalid header base64 decoding';

                return false;
            }

            // Json decode headers
            if (null === ($headers = Json::decode($headers))) {
                $this->errors[] = 'Invalid header json decoding';

                return false;
            }

            // Validate algorithm header
            if (empty($headers->alg)) {
                $this->errors[] = 'Invalid algorithm';

                return false;
            } elseif ( ! Algorithm::validate($headers->alg)) {
                $this->errors[] = 'Unsupported algorithm';

                return false;
            }

            // Base64 decode payload
            if (false === ($payload = Base64::decode($payload))) {
                $this->errors[] = 'Invalid payload base64 decoding';

                return false;
            }

            // Json decode payload
            if (null === ($payload = Json::decode($payload))) {
                $this->errors[] = 'Invalid payload json decoding';

                return false;
            }

            // Base64 decode payload
            if (false === ($signature = Base64::decode($signature))) {
                $this->errors[] = 'Invalid signature base64 decoding';

                return false;
            }

            if (Signature::verify($token, $signature, $key, $headers->alg) === false) {
                $this->errors[] = 'Invalid signature';

                return false;
            }

            // Check if the nbf if it is defined. This is the time that the
            // token can actually be used. If it's not yet that time, abort.
            if (isset($payload->nbf) && $payload->nbf > $timestamp) {
                $this->errors[] = 'Cannot handle token prior to ' . date(\DateTime::ISO8601, $payload->nbf);

                return false;
            }

            // Check that this token has been created before 'now'. This prevents
            // using tokens that have been created for later use (and haven't
            // correctly used the nbf claim).
            if (isset($payload->iat) && $payload->iat > $timestamp) {
                $this->errors[] = 'Cannot handle token prior to ' . date(\DateTime::ISO8601, $payload->iat);

                return false;
            }
            // Check if this token has expired.
            if (isset($payload->exp) && $timestamp >= $payload->exp) {
                $this->errors[] = 'Expired token';

                return false;
            }

            return $payload;
        }

        return false;
    }
411185
public function getHeader($key = null)
    {
        if (is_null($key)) {
            return $this->header;
        }

        return isset($this->header[$key]) ? $this->header[$key] : null;
    }
1212663
protected function serverParamKeyToHeaderName($key)
    {
        $name = null;
        
        if (\Jasny\str_starts_with($key, 'HTTP_')) {
            $name = $this->headerCase(substr($key, 5));
        } elseif (in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH'])) {
            $name = $this->headerCase($key);
        }
            
        return $name;
    }
62924
private function checkUsage(JWKInterface $key, $usage)
    {
        $use = $key->get('use');
        switch ($usage) {
            case 'verification':
            case 'signature':
                Assertion::eq('sig', $use, 'Key cannot be used to sign or verify a signature');

                return true;
            case 'encryption':
            case 'decryption':
                Assertion::eq('enc', $use, 'Key cannot be used to encrypt or decrypt');

                return true;
            default:
                throw new \InvalidArgumentException('Unsupported key usage.');
        }
    }
35849
protected function _signParameters(array $parameters, $key) {
        $algorithm = $this->options['SignatureMethod'];
        $stringToSign = null;
        if (2 === $this->options['SignatureVersion']) {
            $stringToSign = $this->_calculateStringToSignV2($parameters);
//            var_dump($stringToSign);
        } else {
            throw new Exception("Invalid Signature Version specified");
        }
        return $this->_sign($stringToSign, $key, $algorithm);
    }
308065
public function getResponseHeader($key = null) {
        if (null != $key) {
            if (array_key_exists($key, $this->response_headers)) {
                return $this->response_headers[$key];
            }
        } else {
            return $this->response_headers;
        }
    }
1282904
public function sign($payload, $key)
    {
        if (!$key instanceof Key) {
            $key = new Key($key);
        }
        $privateKey = $this->keyParser->parsePrivateKey($key->getContent());

        $hash = $this->hash($payload);

        $random = RandomGeneratorFactory::getRandomGenerator();
        $randomK = $random->generate($this->config->getGenerator()->getOrder());

        $signer = new EccSigner($this->adapter);
        $signature = $signer->sign($privateKey, $hash, $randomK);

        return new LcobucciJWTSignature($this->serializer->serialize($signature, $this->config->getSignatureLength()));
    }
126855
public function getJson($key)
    {
        $signature = array();
        $signature['protected'] = self::base64Encode(Parser::encode($this->headers));
        $signature['payload']   = self::base64Encode($this->claim);
        $signature['signature'] = $this->getEncodedSignature($key);

        return Parser::encode($signature);
    }
1082503
public function getHeader($key)
    {
        $key = str_replace('-', '_', strtoupper($key));

        if ($this->hasHeader($key)) {
            return $_SERVER[$key];
        }

        if ($this->hasHeader('HTTP_'.$key)) {
            return $_SERVER['HTTP_'.$key];
        }

        return null;
    }
1352434
final protected function hhmac($string, $api_key_secret) {
    $key = base64_decode($api_key_secret);
    $hashed = hash_hmac('sha256', $string, $key, true);
    $encoded = base64_encode($hashed);
    $signature = rtrim($encoded, "\n");
    return strval($signature);
  }
840035
public static function createJWSWithDetachedPayloadToCompactJSON($payload, JWKInterface $signature_key, array $protected_headers, LoggerInterface $logger = null)
    {
        $jws = self::createJWSWithDetachedPayloadAndSign($payload, $signature_key, $protected_headers, [], $logger);

        return $jws->toCompactJSON(0);
    }
790416
private function decryptRecipientKey(Object\JWEInterface &$jwe, Object\JWKSetInterface $jwk_set, $i)
    {
        $recipient = $jwe->getRecipient($i);
        $complete_headers = array_merge($jwe->getSharedProtectedHeaders(), $jwe->getSharedHeaders(), $recipient->getHeaders());
        $this->checkCompleteHeader($complete_headers);

        $key_encryption_algorithm = $this->getKeyEncryptionAlgorithm($complete_headers);
        $content_encryption_algorithm = $this->getContentEncryptionAlgorithm($complete_headers);

        foreach ($jwk_set as $jwk) {
            try {
                $this->checkKeyUsage($jwk, 'decryption');
                if ('dir' !== $key_encryption_algorithm->getAlgorithmName()) {
                    $this->checkKeyAlgorithm($jwk, $key_encryption_algorithm->getAlgorithmName());
                } else {
                    $this->checkKeyAlgorithm($jwk, $content_encryption_algorithm->getAlgorithmName());
                }
                $cek = $this->decryptCEK($key_encryption_algorithm, $content_encryption_algorithm, $jwk, $recipient, $complete_headers);
                if (null !== $cek) {
                    if (true === $this->decryptPayload($jwe, $cek, $content_encryption_algorithm, $complete_headers)) {
                        return $i;
                    }
                }
            } catch (\Exception $e) {
                //We do nothing, we continue with other keys
                continue;
            }
        }
    }
1262449
public function verify(JWSInterface $jws, JWKSetInterface $signature_key_set, $detached_payload = null)
    {
        Assertion::inArray($jws->getSignature(0)->getProtectedHeader('alg'), $this->getSupportedSignatureAlgorithms(), sprintf('The signature algorithm "%s" is not supported or not allowed.', $jws->getSignature(0)->getProtectedHeader('alg')));

        $index = null;
        $this->verifier->verifyWithKeySet($jws, $signature_key_set, $detached_payload, $index);
        Assertion::notNull($index, 'JWS signature(s) verification failed.');
        $this->checker_manager->checkJWS($jws, $index);

        return $index;
    }
1204707
public function signResponse(
        ResponseInterface $response,
        SigningSecretKey $secretKey
    ): ResponseInterface {
        $signature = \ParagonIE_Sodium_Compat::crypto_sign_detached(
            (string) $response->getBody(),
            $secretKey->getString(true)
        );
        return $response->withAddedHeader(
            (string) static::HEADER_SIGNATURE_NAME,
            Base64UrlSafe::encode($signature)
        );
    }