private function decryptIdToken(string $idToken)
{
$private_key = openssl_pkey_get_private(
‘file://’ . $this->getParameter(‘jwt_secret_key_path’),
$this->getParameter(‘jwt_secret_key_passphrase’),
);

$parts = explode(‘.’, $idToken);

list($encodedHeader, $encodedEncryptedKey, $encodedIV, $encodedCiphertext, $encodedTag) = $parts;

$encryptedKey = $this->base64url_decode($encodedEncryptedKey);
$iv = $this->base64url_decode($encodedIV);
$ciphertext = $this->base64url_decode($encodedCiphertext);
$tag = $this->base64url_decode($encodedTag);

if (strlen($iv) !== 16) {
throw new Exception(“Invalid IV size. Must be 16 bytes.”);
}
$decryptedKey = ;
if (!openssl_private_decrypt($encryptedKey, $decryptedKey, $private_key, OPENSSL_PKCS1_OAEP_PADDING)) {
throw new Exception(“Failed to decrypt the encryption key.”);
}
$aesKey = substr($decryptedKey, 0, 16);
$hmacKey = substr($decryptedKey, 16);
$plaintext = openssl_decrypt($ciphertext, ‘aes-128-cbc’, $aesKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
$pad = ord($plaintext[strlen($plaintext) 1]);
$plaintext = substr($plaintext, 0, $pad);

if ($plaintext === false) {
while ($msg = openssl_error_string()) {
echo “OpenSSL error: $msg<br/>”;
}
throw new Exception(“Failed to decrypt the ciphertext.”);
}
$recomputedTag = hash_hmac(‘sha256’, $encodedHeader . ‘.’ . $encodedEncryptedKey . ‘.’ . $encodedIV . ‘.’ . $encodedCiphertext, $hmacKey, true);
$recomputedTag = substr($recomputedTag, 0, 16);
if (!hash_equals($tag, $recomputedTag)) {
throw new Exception(“Invalid authentication tag.”);
}
return json_decode($plaintext, true);
}