/********EXTERNAL OBJECT PUBLIC METHODS  - END ********/


        /// <summary>
        /// Encrypts the string encoded plain text
        /// </summary>
        /// <param name="asymmetricEncryptionAlgorithm">string AsymmetricEncryptionAlgorithm enum, algorithm name</param>
        /// <param name="hashAlgorithm">string HashAlgorithm enum, algorithm name</param>
        /// <param name="asymmetricEncryptionPadding">string AsymmetricEncryptionPadding enum, padding name</param>
        /// <param name="keyPath">string path to key/certificate</param>
        /// <param name="isPrivate">boolean true if key is private, false if it is public</param>
        /// <param name="alias">string keystore/certificate pkcs12 format alias</param>
        /// <param name="password">Srting keysore/certificate pkcs12 format alias</param>
        /// <param name="plainText">string to encrypt</param>
        /// <returns>string Base64 encrypted plainText text</returns>
        private string DoEncryptInternal(string hashAlgorithm, string asymmetricEncryptionPadding, Key key, bool isPrivate, string plainText)
        {
            this.error.cleanError();

            HashAlgorithm hash = HashAlgorithmUtils.getHashAlgorithm(hashAlgorithm, this.error);
            AsymmetricEncryptionPadding padding = AsymmetricEncryptionPaddingUtils.getAsymmetricEncryptionPadding(asymmetricEncryptionPadding, this.error);

            if (this.error.existsError())
            {
                return("");
            }

            string asymmetricEncryptionAlgorithm = "";
            AsymmetricKeyParameter asymKey       = null;

            if (isPrivate)
            {
                PrivateKeyManager keyMan = (PrivateKeyManager)key;
                if (!keyMan.HasPrivateKey || keyMan.HasError())
                {
                    this.error = keyMan.GetError();
                    return("");
                }
                asymmetricEncryptionAlgorithm = keyMan.getPrivateKeyAlgorithm();

                asymKey = keyMan.getPrivateKeyParameterForEncryption();
                if (keyMan.HasError())
                {
                    this.error = keyMan.GetError();
                    return("");
                }
            }
            else
            {
                CertificateX509 cert = (CertificateX509)key;
                if (!cert.Inicialized || cert.HasError())
                {
                    this.error = cert.GetError();
                    return("");
                }
                asymmetricEncryptionAlgorithm = cert.getPublicKeyAlgorithm();
                asymKey = cert.getPublicKeyParameterForEncryption();
                if (cert.HasError())
                {
                    this.error = cert.GetError();
                    return("");
                }
            }

            AsymmetricEncryptionAlgorithm algorithm = AsymmetricEncryptionAlgorithmUtils
                                                      .getAsymmetricEncryptionAlgorithm(asymmetricEncryptionAlgorithm, this.error);

            try
            {
                return(doEncrypt(algorithm, hash, padding, asymKey, plainText));
            }
            catch (InvalidCipherTextException)
            {
                this.error.setError("AE036", "Algoritmo inválido" + algorithm);

                return("");
            }
        }
        /********EXTERNAL OBJECT PUBLIC METHODS  - END ********/

        private String Sign(PrivateKey key, string hashAlgorithm, Stream input)
        {
            PrivateKeyManager keyMan = (PrivateKeyManager)key;

            if (keyMan.HasError())
            {
                this.error = keyMan.GetError();
                return("");
            }
            AsymmetricSigningAlgorithm asymmetricSigningAlgorithm = AsymmetricSigningAlgorithmUtils
                                                                    .GetAsymmetricSigningAlgorithm(keyMan.getPrivateKeyAlgorithm(), this.error);

            if (this.HasError())
            {
                return("");
            }
            ISigner signer = AsymmetricSigningAlgorithmUtils.GetSigner(asymmetricSigningAlgorithm, GetHash(hashAlgorithm),
                                                                       this.error);

            if (this.HasError())
            {
                return("");
            }
            SetUpSigner(signer, input, keyMan.getPrivateKeyParameterForSigning(), true);
            if (this.HasError())
            {
                return("");
            }
            byte[] outputBytes = null;
            try
            {
                outputBytes = signer.GenerateSignature();
            }
            catch (Exception e)
            {
                error.setError("AE01", e.Message);
                return("");
            }
            String result = "";

            try
            {
                result = Base64.ToBase64String(outputBytes);
            }
            catch (Exception e)
            {
                error.setError("AE018", e.Message);
                return("");
            }
            return(result);
        }
        public string DoCreate(string algorithm, PrivateClaims privateClaims, JWTOptions options)
        {
            this.error.cleanError();
            if (options.HasError())
            {
                this.error = options.GetError();
                return("");
            }
            JWTAlgorithm alg = JWTAlgorithmUtils.getJWTAlgorithm(algorithm, this.error);

            if (this.HasError())
            {
                return("");
            }
            if (this.HasError())
            {
                return("");
            }
            /***Hack to support 1024 RSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS256"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS512"] = 1024;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["RS384"] = 1024;
            /***Hack to support 1024 RSA key lengths - END***/

            /***Hack to support 192 ECDSA key lengths - BEGIN***/
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES256"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES512"] = 112;
            AsymmetricSignatureProvider.DefaultMinimumAsymmetricKeySizeInBitsForSigningMap["ES384"] = 112;
            /***Hack to support 192 ECDSA key lengths - END***/

            JwtPayload payload = doBuildPayload(privateClaims, options);

            SecurityKey genericKey = null;

            if (JWTAlgorithmUtils.isPrivate(alg))
            {
                PrivateKeyManager key = options.GetPrivateKey();
                if (key.HasError())
                {
                    this.error = key.GetError();
                    return("");
                }
                if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "RSA"))
                {
                    try
                    {
                        genericKey = new RsaSecurityKey((RSA)key.getPrivateKeyForJWT());
                    }catch (Exception)
                    {
                        this.error = key.GetError();
                        return("");
                    }
                }
                else if (SecurityUtils.compareStrings(key.getPrivateKeyAlgorithm(), "ECDSA"))
                {
                    try {
                        genericKey = new ECDsaSecurityKey((ECDsa)key.getPrivateKeyForJWT());
                    }
                    catch (Exception)
                    {
                        this.error = key.GetError();
                        return("");
                    }
                }
                else
                {
                    this.error.setError("JW012", "Not recognized key algorithm");
                    return("");
                }
                if (genericKey == null)
                {
                    this.error = key.GetError();
                    return("");
                }
            }
            else
            {
                SymmetricSecurityKey symKey = new SymmetricSecurityKey(options.getSecret());
                genericKey = symKey;
            }

            SigningCredentials signingCredentials = JWTAlgorithmUtils.getSigningCredentials(alg, genericKey, this.error);

            if (this.HasError())
            {
                return("");
            }

            string signedJwt = "";

            try
            {
                JwtHeader header = new JwtHeader(signingCredentials);
                if (!options.GetHeaderParameters().IsEmpty())
                {
                    AddHeaderParameters(header, options);
                }

                JwtSecurityToken        secToken = new JwtSecurityToken(header, payload);
                JwtSecurityTokenHandler handler  = new JwtSecurityTokenHandler();
                signedJwt = handler.WriteToken(secToken);
            }
            catch (Exception e)
            {
                this.error.setError("JW003", "key size: " + /*genericKey.KeySize.ToString()*/ e.Message + e.StackTrace);

                return("");
            }

            return(signedJwt);
        }