public static JsonGeneral Import(string jwe)
        {
            JsonGeneral result;

            try
            {
                result = JsonConvert.DeserializeObject <JsonGeneral>(jwe);
            }
            catch (Exception)
            {
                string[] parts = jwe.Split('.');

                result = new JsonGeneral
                {
                    ProtectedHeader      = parts[0],
                    EncryptedKey         = parts[1],
                    InitializationVector = parts[2],
                    CipherText           = parts[3],
                    AuthenticationTag    = parts[4],
                };
            }

            if (result == null)
            {
                throw new Exception("Wrong JWE format");
            }

            return(result);
        }
        private void Encrypt(object key)
        {
            var alg = _keyAlgorithms[(Algorithms)_protectedHeader.Algorithm];
            var enc = _encAlgorithms[(Encryptions)_protectedHeader.EncryptionAlgorithm];

            if (alg == null)
            {
                throw new Exception("Unsupported JWA algorithm requested");
            }

            if (enc == null)
            {
                throw new Exception("Unsupported JWE encryption requested");
            }

            var cek          = Utils.Random(enc.KeySize);
            var iv           = Utils.Random(128);
            var encryptedCek = alg.WrapKey(cek, key);
            var encParts     = enc.Encrypt(Base64Url.Decode(_message), cek, iv, _aad != null ? Base64Url.Decode(_aad) : new byte[0]);

            _result = new JsonGeneral
            {
                ProtectedHeader             = Base64Url.Encode(JsonConvert.SerializeObject(_protectedHeader)),
                EncryptedKey                = Base64Url.Encode(encryptedCek),
                AdditionalAuthenticatedData = _aad,
                InitializationVector        = Base64Url.Encode(iv),
                CipherText        = Base64Url.Encode(encParts[0]),
                AuthenticationTag = Base64Url.Encode(encParts[1]),
            };
        }
        public static byte[] Decrypt(JsonGeneral jwe, object key)
        {
            var protectedHeader = JsonConvert.DeserializeObject <JsonHeader>(Encoding.UTF8.GetString(Base64Url.Decode(jwe.ProtectedHeader)));
            var enc             = _encAlgorithms[(Encryptions)protectedHeader.EncryptionAlgorithm];

            if (enc == null)
            {
                throw new Exception("Unsupported JWE encryption requested");
            }

            byte[] cek = null;

            if (jwe.EncryptedKey != null)
            {
                var alg = _keyAlgorithms[(Algorithms)protectedHeader.Algorithm];

                if (alg == null)
                {
                    throw new Exception("Unsupported JWA algorithm requested");
                }

                var encryptedKey = Base64Url.Decode(jwe.EncryptedKey);
                cek = alg.UnwrapKey(encryptedKey, key);
            }
            else if (jwe.Recipients != null)
            {
                foreach (var recipient in jwe.Recipients)
                {
                    var alg = _keyAlgorithms[(Algorithms)recipient.Header.Algorithm];

                    if (alg == null)
                    {
                        throw new Exception("Unsupported JWA algorithm requested");
                    }

                    var encryptedKey = Base64Url.Decode(recipient.EncryptedKey);

                    try
                    {
                        cek = alg.UnwrapKey(encryptedKey, key);

                        break;
                    }
                    catch (Exception) { }
                }
            }

            var iv  = Base64Url.Decode(jwe.InitializationVector);
            var aad = jwe.AdditionalAuthenticatedData != null?Base64Url.Decode(jwe.AdditionalAuthenticatedData) : new byte[0];

            var cipherText = Base64Url.Decode(jwe.CipherText);
            var tag        = Base64Url.Decode(jwe.AuthenticationTag);

            return(enc.Decrypt(cipherText, cek, iv, aad, tag));
        }