private string InternalDecrypt(string payload, JsonWebKey jsonWebKey, byte[] hmacKey = null) { IEnumerable <string> parts = null; if (!IsValid(payload, out parts)) { throw new JwtException(ErrorCodes.INTERNAL_ERROR, ErrorMessages.INVALID_JWE); } var serializedProtectedHeader = parts.ElementAt(0).Base64Decode(); var encryptedContentEncryptionKeyBytes = parts.ElementAt(1).Base64DecodeBytes(); var iv = parts.ElementAt(2).Base64DecodeBytes(); var cipherText = parts.ElementAt(3).Base64DecodeBytes(); var authenticationTag = parts.ElementAt(4).Base64DecodeBytes(); var protectedHeader = JsonConvert.DeserializeObject(serializedProtectedHeader) as JObject; var alg = protectedHeader["alg"].ToString(); var enc = protectedHeader["enc"].ToString(); var contentEncryptionKeyHandler = _cekHandlers.FirstOrDefault(e => e.AlgName == alg); var encEncryptionHandler = _encHandlers.FirstOrDefault(e => e.EncName == enc); if (contentEncryptionKeyHandler == null || encEncryptionHandler == null) { return(null); } var cek = contentEncryptionKeyHandler.Decrypt(encryptedContentEncryptionKeyBytes, jsonWebKey); var splittedCEK = BitHelper.SplitInHalf(cek); if (hmacKey == null) { hmacKey = splittedCEK.First(); } var decrypted = encEncryptionHandler.Decrypt(cipherText, splittedCEK.Last(), iv); var aad = Encoding.ASCII.GetBytes(Encoding.UTF8.GetBytes(serializedProtectedHeader).Base64EncodeBytes()); var al = BitHelper.LongToBytes(aad.Length * 8); var hmacInput = BitHelper.Concat(aad, iv, cipherText, al); var hmacValue = encEncryptionHandler.BuildHash(hmacKey, hmacInput); var newAuthenticationTag = BitHelper.SplitInHalf(hmacValue)[0]; if (!BitHelper.ConstantTimeEquals(newAuthenticationTag, authenticationTag)) { return(null); } return(decrypted); }