/** * @param Context $context * @param string $token * @param string|resource $key * * @return string */ public static function decode(Context $context, $token, $key) { if (empty($token) || trim($token) === '') { throw new JoseJwtException('Incoming token expected to be in compact serialization form, but is empty'); } $parts = explode('.', $token); if (count($parts) != 5) { throw new JoseJwtException('Invalid JWE token'); } $decodedParts = []; foreach ($parts as $part) { $decodedParts[] = UrlSafeB64Encoder::decode($part); } $headerString = $decodedParts[0]; $encryptedCek = $decodedParts[1]; $iv = $decodedParts[2]; $cipherText = $decodedParts[3]; $authTag = $decodedParts[4]; $header = json_decode($headerString, true); if (null === $header) { throw new JoseJwtException('Invalid header'); } $algorithm = $context->jweAlgorithms()->get($header['alg']); $encryption = $context->jweEncryptions()->get($header['enc']); $cek = $algorithm->unwrap($encryptedCek, $key, $encryption->getKeySize(), $header); $aad = $parts[0]; $plainText = $encryption->decrypt($aad, $cek, $iv, $cipherText, $authTag); return $plainText; }
/** * @param Context $context * @param array|object $payload * @param string|resource $key * @param string $jwsAlgorithm * @param array $extraHeaders * * @return string */ public static function encode(Context $context, $payload, $key, $jwsAlgorithm, $extraHeaders = []) { $header = array_merge(['alg' => '', 'typ' => 'JWT'], $extraHeaders); $hashAlgorithm = $context->jwsAlgorithms()->get($jwsAlgorithm); if (null == $hashAlgorithm) { throw new JoseJwtException(sprintf('Unknown algorithm "%s"', $jwsAlgorithm)); } $header['alg'] = $jwsAlgorithm; $payloadString = StringUtils::payload2string($payload, $context->jsonMapper()); $signingInput = implode('.', [UrlSafeB64Encoder::encode(json_encode($header)), UrlSafeB64Encoder::encode($payloadString)]); $signature = $hashAlgorithm->sign($signingInput, $key); $signature = UrlSafeB64Encoder::encode($signature); return $signingInput . '.' . $signature; }