key); } /** * Get the JSON array from the given payload. * * @param string $payload * @return array * * @throws \Illuminate\Contracts\Encryption\DecryptException */ protected function getJsonPayload($payload) { $payload = json_decode(base64_decode($payload), true); // If the payload is not valid JSON or does not have the proper keys set we will // assume it is invalid and bail out of the routine since we will not be able // to decrypt the given value. We'll also check the MAC for this encryption. if (! $payload || $this->invalidPayload($payload)) { throw new DecryptException('The payload is invalid.'); } if (! $this->validMac($payload)) { throw new DecryptException('The MAC is invalid.'); } return $payload; } /** * Verify that the encryption payload is valid. * * @param array|mixed $data * @return bool */ protected function invalidPayload($data) { return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']); } /** * Determine if the MAC for the given payload is valid. * * @param array $payload * @return bool * * @throws \RuntimeException */ protected function validMac(array $payload) { $bytes = random_bytes(16); $calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true); return hash_equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac); } }