Beispiel #1
0
        public object SetKeys(string publicKey, string privateKeyEnc)
        {
            SecurityContext.DemandPermissions(new UserSecurityProvider(SecurityContext.CurrentAccount.ID), Core.Users.Constants.Action_EditUser);

            if (!PrivacyRoomSettings.Enabled)
            {
                throw new System.Security.SecurityException();
            }

            var keyPair = EncryptionKeyPair.GetKeyPair();

            if (keyPair != null)
            {
                if (!string.IsNullOrEmpty(keyPair.PublicKey))
                {
                    return(new { isset = true });
                }

                LogManager.GetLogger("ASC.Api.Documents").InfoFormat("User {0} updates address", SecurityContext.CurrentAccount.ID);
            }

            EncryptionKeyPair.SetKeyPair(publicKey, privateKeyEnc);

            return(new
            {
                isset = true
            });
        }
Beispiel #2
0
        public IEnumerable <EncryptionKeyPair> GetPublicKeysWithAccess(string fileId)
        {
            if (!PrivacyRoomSettings.Enabled)
            {
                throw new System.Security.SecurityException();
            }

            var fileKeyPair = EncryptionKeyPair.GetKeyPair(fileId);

            return(fileKeyPair);
        }
Beispiel #3
0
        public void Decrypting_UsingPublicKey_Exc()
        {
            Setup.Initialize(out var testFolders);
            Setup.SetEncryptedFiles(testFolders);

            string targetFilePath = Directory.GetFiles(testFolders["encrypted"])[0];
            var    key            = EncryptionKeyPair.ImportPEMFile($@"{Setup.AbsolutePath}\pub.key.pem");

            Assert.NotNull(key);

            Assert.Throws <InvalidOperationException>(()
                                                      => Program.DecryptOption(targetFilePath, Setup.PublicKey, testFolders["decrypted"], false));
        }
            /// <summary>
            ///     Generate Aes encryption key.
            /// </summary>
            /// <returns></returns>
            public static EncryptionKeyPair GenerateKeyPair()
            {
                var ret = new EncryptionKeyPair();

                using var aes = System.Security.Cryptography.Aes.Create();
                aes.GenerateKey();
                ret.PublicKey = aes.Key;

                aes.GenerateIV();
                ret.PrivateKey = aes.IV;

                return(ret);
            }
Beispiel #5
0
        public static void Initialize(out Dictionary <string, string> testFolders)
        {
            Guid[] guids =
            {
                Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()
            };
            string folderName = Guid.NewGuid().ToString();

            testFolders = new Dictionary <string, string>
            {
                { "original", Path.Combine(OriginalPath, folderName) },
                { "encrypted", Path.Combine(EncryptedPath, folderName) },
                { "decrypted", Path.Combine(DecryptedPath, folderName) },
            };

            string[] files =
            {
                Path.Combine(testFolders["original"], guids[0].ToString() + ".txt"),
                Path.Combine(testFolders["original"], guids[1].ToString() + ".txt"),
                Path.Combine(testFolders["original"], guids[2].ToString() + ".txt"),
            };

            string pubKey  = @$ "{AbsolutePath}\pub.key.pem";
            string privKey = @$ "{AbsolutePath}\priv.key.pem";

            Directory.CreateDirectory(testFolders["original"]);
            Directory.CreateDirectory(testFolders["encrypted"]);
            Directory.CreateDirectory(testFolders["decrypted"]);

            for (int i = 0; i < files.Length; i++)
            {
                using (var sw = File.CreateText(files[i]))
                {
                    sw.WriteLine(Guid.NewGuid());
                    sw.WriteLine(Guid.NewGuid());
                    sw.WriteLine(Guid.NewGuid());
                }
            }

            if (!File.Exists(pubKey) && !File.Exists(privKey))
            {
                var key = EncryptionKeyPair.New(2048);
                key.ExportAsPEMFile(AbsolutePath, includePrivate: false);
                key.ExportAsPEMFile(AbsolutePath, includePrivate: true);
            }

            PrivateKey = EncryptionKeyPair.ImportPEMFile(@$ "{AbsolutePath}\priv.key.pem");
            PublicKey  = EncryptionKeyPair.ImportPEMFile(@$ "{AbsolutePath}\pub.key.pem");
        }
        public EncryptionKeyPair GenerateEncryptionKeyPair()
        {
            using (var cryptoProvider = new RNGCryptoServiceProvider())
            {
                var    key = Guid.NewGuid().ToString("N");
                byte[] secretKeyByteArray = new byte[32];                 //256 bit
                cryptoProvider.GetBytes(secretKeyByteArray);
                var secret = Convert.ToBase64String(secretKeyByteArray);
                var result = new EncryptionKeyPair
                {
                    PublicKey  = key,
                    PrivateKey = secret
                };

                return(result);
            }
        }
        private void PageLoad()
        {
            var editPossible = !RequestEmbedded;
            var isExtenral   = false;

            File file;
            var  fileUri = string.Empty;

            try
            {
                if (string.IsNullOrEmpty(RequestFileUrl))
                {
                    var app = ThirdPartySelector.GetAppByFileId(RequestFileId);
                    if (app == null)
                    {
                        file = DocumentServiceHelper.GetParams(RequestFileId, RequestVersion, RequestShareLinkKey, editPossible, !RequestView, true, out _configuration);
                        if (_valideShareLink)
                        {
                            _configuration.Document.SharedLinkKey += RequestShareLinkKey;
                            _configuration.Document.Info.Favorite  = null;

                            if (CoreContext.Configuration.Personal && !SecurityContext.IsAuthenticated)
                            {
                                var user    = CoreContext.UserManager.GetUsers(file.CreateBy);
                                var culture = CultureInfo.GetCultureInfo(user.CultureName);
                                Thread.CurrentThread.CurrentCulture   = culture;
                                Thread.CurrentThread.CurrentUICulture = culture;
                            }
                        }
                    }
                    else
                    {
                        isExtenral = true;

                        bool editable;
                        _thirdPartyApp = true;
                        file           = app.GetFile(RequestFileId, out editable);
                        file           = DocumentServiceHelper.GetParams(file, true, editPossible ? FileShare.ReadWrite : FileShare.Read, false, editable, editable, editable, true, out _configuration);

                        _configuration.Document.Url = app.GetFileStreamUrl(file);
                        _configuration.EditorConfig.Customization.GobackUrl = string.Empty;
                        _configuration.Document.Info.Favorite = null;
                    }
                }
                else
                {
                    isExtenral = true;

                    fileUri = RequestFileUrl;
                    var fileTitle = Request[FilesLinkUtility.FileTitle];
                    if (string.IsNullOrEmpty(fileTitle))
                    {
                        fileTitle = Path.GetFileName(HttpUtility.UrlDecode(fileUri)) ?? "";
                    }

                    file = new File
                    {
                        ID    = RequestFileUrl,
                        Title = Global.ReplaceInvalidCharsAndTruncate(fileTitle)
                    };

                    file = DocumentServiceHelper.GetParams(file, true, FileShare.Read, false, false, false, false, false, out _configuration);
                    _configuration.Document.Permissions.Edit          = editPossible && !CoreContext.Configuration.Standalone;
                    _configuration.Document.Permissions.Rename        = false;
                    _configuration.Document.Permissions.Review        = false;
                    _configuration.Document.Permissions.FillForms     = false;
                    _configuration.Document.Permissions.ChangeHistory = false;
                    _configuration.Document.Permissions.ModifyFilter  = false;
                    _editByUrl = true;

                    _configuration.Document.Url           = fileUri;
                    _configuration.Document.Info.Favorite = null;
                }
                ErrorMessage = _configuration.ErrorMessage;
            }
            catch (Exception ex)
            {
                Global.Logger.Warn("DocEditor", ex);
                ErrorMessage = ex.Message;
                return;
            }

            var        userAgent      = Request.UserAgent.ToString().ToLower();
            HttpCookie deeplinkCookie = Request.Cookies.Get("deeplink");
            var        deepLink       = ConfigurationManagerExtension.AppSettings["deeplink.documents.url"];

            if (!_valideShareLink &&
                deepLink != null && MobileDetector.IsMobile &&
                ((!userAgent.Contains("version/") && userAgent.Contains("android")) || !userAgent.Contains("android")) &&       //check webkit
                ((Request[DeepLinking.WithoutDeeplinkRedirect] == null && deeplinkCookie == null) ||
                 Request[DeepLinking.WithoutDeeplinkRedirect] == null && deeplinkCookie != null && deeplinkCookie.Value == "app"))
            {
                var          currentUser  = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID);
                DeepLinkData deepLinkData = new DeepLinkData
                {
                    Email  = currentUser.Email,
                    Portal = CoreContext.TenantManager.GetCurrentTenant().TenantDomain,
                    File   = new DeepLinkDataFile
                    {
                        Id        = file.ID.ToString(),
                        Title     = file.Title,
                        Extension = file.ConvertedExtension
                    },
                    Folder = new DeepLinkDataFolder
                    {
                        Id             = file.FolderID.ToString(),
                        ParentId       = file.RootFolderId.ToString(),
                        RootFolderType = (int)file.RootFolderType
                    },
                    OriginalUrl = Request.GetUrlRewriter().ToString()
                };

                var    jsonDeeplinkData   = JsonConvert.SerializeObject(deepLinkData);
                string base64DeeplinkData = Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonDeeplinkData));

                Response.Redirect("~/DeepLink.aspx?data=" + HttpUtility.UrlEncode(base64DeeplinkData));
            }


            if (_configuration.EditorConfig.ModeWrite && FileConverter.MustConvert(file))
            {
                try
                {
                    file = FileConverter.ExecSync(file, RequestShareLinkKey);
                }
                catch (Exception ex)
                {
                    _configuration = null;
                    Global.Logger.Error("DocEditor", ex);
                    ErrorMessage = ex.Message;
                    return;
                }

                var comment = "#message/" + HttpUtility.UrlEncode(string.Format(FilesCommonResource.ConvertForEdit, file.Title));

                Response.Redirect(FilesLinkUtility.GetFileWebEditorUrl(file.ID) + comment);
                return;
            }

            var fileSecurity = Global.GetFilesSecurity();

            if (_configuration.EditorConfig.ModeWrite &&
                FileUtility.CanWebRestrictedEditing(file.Title) &&
                fileSecurity.CanFillForms(file) &&
                !fileSecurity.CanEdit(file))
            {
                if (!file.IsFillFormDraft)
                {
                    FileMarker.RemoveMarkAsNew(file);

                    Folder folderIfNew;
                    try
                    {
                        file = EntryManager.GetFillFormDraft(file, out folderIfNew);
                    }
                    catch (Exception ex)
                    {
                        _configuration = null;
                        Global.Logger.Error("DocEditor", ex);
                        ErrorMessage = ex.Message;
                        return;
                    }

                    var comment = folderIfNew == null
                        ? string.Empty
                        : "#message/" + HttpUtility.UrlEncode(string.Format(FilesCommonResource.MessageFillFormDraftCreated, folderIfNew.Title));

                    Response.Redirect(FilesLinkUtility.GetFileWebEditorUrl(file.ID) + comment);
                    return;
                }
                else if (!EntryManager.CheckFillFormDraft(file))
                {
                    var comment = "#message/" + HttpUtility.UrlEncode(FilesCommonResource.MessageFillFormDraftDiscard);

                    Response.Redirect(FilesLinkUtility.GetFileWebEditorUrl(file.ID) + comment);
                    return;
                }
            }

            Title = file.Title + GetPageTitlePostfix();

            if (_configuration.EditorConfig.Customization.Goback == null || string.IsNullOrEmpty(_configuration.EditorConfig.Customization.Goback.Url))
            {
                _configuration.EditorConfig.Customization.GobackUrl = Request[FilesLinkUtility.FolderUrl] ?? "";
            }

            _configuration.EditorConfig.Customization.IsRetina = TenantLogoManager.IsRetina(Request);

            if (RequestEmbedded)
            {
                _configuration.Type = Services.DocumentService.Configuration.EditorType.Embedded;

                _configuration.EditorConfig.Embedded.ShareLinkParam = string.IsNullOrEmpty(RequestShareLinkKey) ? string.Empty : "&" + FilesLinkUtility.DocShareKey + "=" + RequestShareLinkKey;
            }
            else
            {
                _configuration.Type = IsMobile ? Services.DocumentService.Configuration.EditorType.Mobile : Services.DocumentService.Configuration.EditorType.Desktop;

                if (FileSharing.CanSetAccess(file) &&
                    !(file.Encrypted &&
                      (!Request.DesktopApp() ||
                       CoreContext.Configuration.Personal)))
                {
                    _configuration.EditorConfig.SharingSettingsUrl = CommonLinkUtility.GetFullAbsolutePath(
                        Share.Location
                        + "?" + FilesLinkUtility.FileId + "=" + HttpUtility.UrlEncode(file.ID.ToString())
                        + (Request.DesktopApp() ? "&desktop=true" : string.Empty));
                }

                if (file.RootFolderType == FolderType.Privacy)
                {
                    if (!PrivacyRoomSettings.Enabled)
                    {
                        _configuration = null;
                        ErrorMessage   = FilesCommonResource.ErrorMassage_FileNotFound;
                        return;
                    }
                    else
                    {
                        if (Request.DesktopApp())
                        {
                            var keyPair = EncryptionKeyPair.GetKeyPair();
                            if (keyPair != null)
                            {
                                _configuration.EditorConfig.EncryptionKeys = new Services.DocumentService.Configuration.EditorConfiguration.EncryptionKeysConfig
                                {
                                    PrivateKeyEnc = keyPair.PrivateKeyEnc,
                                    PublicKey     = keyPair.PublicKey,
                                };
                            }
                        }
                    }
                }
            }

            if (!isExtenral)
            {
                _docKeyForTrack = DocumentServiceHelper.GetDocKey(file.ID, -1, DateTime.MinValue);

                FileMarker.RemoveMarkAsNew(file);
                if (!file.Encrypted && !file.ProviderEntry)
                {
                    EntryManager.MarkAsRecent(file);
                }

                if (RequestView)
                {
                    FilesMessageService.Send(file, MessageInitiator.DocsService, MessageAction.FileReaded, file.Title);
                }
                else
                {
                    FilesMessageService.Send(file, MessageInitiator.DocsService, MessageAction.FileOpenedForChange, file.Title);
                }
            }

            if (SecurityContext.IsAuthenticated)
            {
                var saveAsUrl = SaveAs.GetUrl;
                using (var folderDao = Global.DaoFactory.GetFolderDao())
                {
                    var folder = folderDao.GetFolder(file.FolderID);
                    if (folder != null && Global.GetFilesSecurity().CanCreate(folder))
                    {
                        saveAsUrl = SaveAs.GetUrlToFolder(file.FolderID);
                    }
                }

                _configuration.EditorConfig.SaveAsUrl = CommonLinkUtility.GetFullAbsolutePath(saveAsUrl);
            }

            if (_configuration.EditorConfig.ModeWrite)
            {
                _tabId = FileTracker.Add(file.ID);

                Global.SocketManager.FilesChangeEditors(file.ID);

                if (SecurityContext.IsAuthenticated)
                {
                    _configuration.EditorConfig.FileChoiceUrl = CommonLinkUtility.GetFullAbsolutePath(FileChoice.GetUrlForEditor);
                }
            }
            else
            {
                _linkToEdit = _editByUrl
                                  ? CommonLinkUtility.GetFullAbsolutePath(FilesLinkUtility.GetFileWebEditorExternalUrl(fileUri, file.Title))
                                  : CommonLinkUtility.GetFullAbsolutePath(FilesLinkUtility.GetFileWebEditorUrl(file.ID));
                if (Request.DesktopApp())
                {
                    _linkToEdit += "&desktop=true";
                }

                if (FileConverter.MustConvert(_configuration.Document.Info.File))
                {
                    _editByUrl = true;
                }
            }

            var actionAnchor = Request[FilesLinkUtility.Anchor];

            if (!string.IsNullOrEmpty(actionAnchor))
            {
                _configuration.EditorConfig.ActionLinkString = actionAnchor;
            }
        }
 /// <summary>
 ///     Using AES algorithm to decrypt input text.
 /// </summary>
 /// <param name="cipherText"></param>
 /// <param name="keyPair"></param>
 /// <returns></returns>
 public static string Decrypt(string cipherText,
                              EncryptionKeyPair keyPair)
 {
     return(Decrypt(cipherText, keyPair.PublicKey, keyPair.PrivateKey));
 }
 /// <summary>
 ///     Using AES algorithm to encrypt input text with output URL friendly encrypted text.
 /// </summary>
 /// <param name="clearText"></param>
 /// <param name="keyPair"></param>
 /// <returns></returns>
 public static string UrlEncrypt(string clearText,
                                 EncryptionKeyPair keyPair)
 {
     return(UrlEncrypt(clearText, keyPair.PublicKey, keyPair.PrivateKey));
 }
Beispiel #10
0
        private void PageLoad()
        {
            var editPossible = !RequestEmbedded;
            var isExtenral   = false;

            File file;
            var  fileUri = string.Empty;

            try
            {
                if (string.IsNullOrEmpty(RequestFileUrl))
                {
                    var app = ThirdPartySelector.GetAppByFileId(RequestFileId);
                    if (app == null)
                    {
                        file = DocumentServiceHelper.GetParams(RequestFileId, RequestVersion, RequestShareLinkKey, editPossible, !RequestView, true, out _configuration);
                        if (_valideShareLink)
                        {
                            _configuration.Document.SharedLinkKey += RequestShareLinkKey;

                            if (CoreContext.Configuration.Personal && !SecurityContext.IsAuthenticated)
                            {
                                var user    = CoreContext.UserManager.GetUsers(file.CreateBy);
                                var culture = CultureInfo.GetCultureInfo(user.CultureName);
                                Thread.CurrentThread.CurrentCulture   = culture;
                                Thread.CurrentThread.CurrentUICulture = culture;
                            }
                        }
                    }
                    else
                    {
                        isExtenral = true;

                        bool editable;
                        _thirdPartyApp = true;
                        file           = app.GetFile(RequestFileId, out editable);
                        file           = DocumentServiceHelper.GetParams(file, true, editPossible ? FileShare.ReadWrite : FileShare.Read, false, editable, editable, editable, true, out _configuration);

                        _configuration.Document.Url = app.GetFileStreamUrl(file);
                        _configuration.EditorConfig.Customization.GobackUrl = string.Empty;
                    }
                }
                else
                {
                    isExtenral = true;

                    fileUri = RequestFileUrl;
                    var fileTitle = Request[FilesLinkUtility.FileTitle];
                    if (string.IsNullOrEmpty(fileTitle))
                    {
                        fileTitle = Path.GetFileName(HttpUtility.UrlDecode(fileUri)) ?? "";
                    }

                    file = new File
                    {
                        ID    = RequestFileUrl,
                        Title = Global.ReplaceInvalidCharsAndTruncate(fileTitle)
                    };

                    file = DocumentServiceHelper.GetParams(file, true, FileShare.Read, false, false, false, false, false, out _configuration);
                    _configuration.Document.Permissions.Edit          = editPossible && !CoreContext.Configuration.Standalone;
                    _configuration.Document.Permissions.Rename        = false;
                    _configuration.Document.Permissions.Review        = false;
                    _configuration.Document.Permissions.FillForms     = false;
                    _configuration.Document.Permissions.ChangeHistory = false;
                    _configuration.Document.Permissions.ModifyFilter  = false;
                    _editByUrl = true;

                    _configuration.Document.Url = fileUri;
                }
                ErrorMessage = _configuration.ErrorMessage;
            }
            catch (Exception ex)
            {
                Global.Logger.Warn("DocEditor", ex);
                ErrorMessage = ex.Message;
                return;
            }

            if (_configuration.EditorConfig.ModeWrite && FileConverter.MustConvert(file))
            {
                try
                {
                    file = FileConverter.ExecSync(file, RequestShareLinkKey);
                }
                catch (Exception ex)
                {
                    _configuration = null;
                    Global.Logger.Error("DocEditor", ex);
                    ErrorMessage = ex.Message;
                    return;
                }

                var comment = "#message/" + HttpUtility.UrlEncode(string.Format(FilesCommonResource.ConvertForEdit, file.Title));

                Response.Redirect(FilesLinkUtility.GetFileWebEditorUrl(file.ID) + comment);
                return;
            }

            Title = file.Title + GetPageTitlePostfix();

            if (_configuration.EditorConfig.Customization.Goback == null || string.IsNullOrEmpty(_configuration.EditorConfig.Customization.Goback.Url))
            {
                _configuration.EditorConfig.Customization.GobackUrl = Request[FilesLinkUtility.FolderUrl] ?? "";
            }

            _configuration.EditorConfig.Customization.IsRetina = TenantLogoManager.IsRetina(Request);

            if (RequestEmbedded)
            {
                _configuration.Type = Services.DocumentService.Configuration.EditorType.Embedded;

                _configuration.EditorConfig.Embedded.ShareLinkParam = string.IsNullOrEmpty(RequestShareLinkKey) ? string.Empty : "&" + FilesLinkUtility.DocShareKey + "=" + RequestShareLinkKey;
            }
            else
            {
                _configuration.Type = IsMobile ? Services.DocumentService.Configuration.EditorType.Mobile : Services.DocumentService.Configuration.EditorType.Desktop;

                if (FileSharing.CanSetAccess(file) &&
                    !(file.Encrypted &&
                      (!Request.DesktopApp() ||
                       CoreContext.Configuration.Personal)))
                {
                    _configuration.EditorConfig.SharingSettingsUrl = CommonLinkUtility.GetFullAbsolutePath(
                        Share.Location
                        + "?" + FilesLinkUtility.FileId + "=" + HttpUtility.UrlEncode(file.ID.ToString())
                        + (Request.DesktopApp() ? "&desktop=true" : string.Empty));
                }

                if (file.RootFolderType == FolderType.Privacy)
                {
                    if (!PrivacyRoomSettings.Enabled)
                    {
                        _configuration = null;
                        ErrorMessage   = FilesCommonResource.ErrorMassage_FileNotFound;
                        return;
                    }
                    else
                    {
                        if (Request.DesktopApp())
                        {
                            var keyPair = EncryptionKeyPair.GetKeyPair();
                            if (keyPair != null)
                            {
                                _configuration.EditorConfig.EncryptionKeys = new Services.DocumentService.Configuration.EditorConfiguration.EncryptionKeysConfig
                                {
                                    PrivateKeyEnc = keyPair.PrivateKeyEnc,
                                    PublicKey     = keyPair.PublicKey,
                                };
                            }
                        }
                    }
                }
            }

            if (!isExtenral)
            {
                _docKeyForTrack = DocumentServiceHelper.GetDocKey(file.ID, -1, DateTime.MinValue);

                FileMarker.RemoveMarkAsNew(file);
                if (!file.Encrypted && !file.ProviderEntry)
                {
                    EntryManager.MarkAsRecent(file);
                }
            }

            if (SecurityContext.IsAuthenticated)
            {
                _configuration.EditorConfig.SaveAsUrl = CommonLinkUtility.GetFullAbsolutePath(SaveAs.GetUrl);
            }

            if (_configuration.EditorConfig.ModeWrite)
            {
                _tabId = FileTracker.Add(file.ID);

                Global.SocketManager.FilesChangeEditors(file.ID);

                if (SecurityContext.IsAuthenticated)
                {
                    _configuration.EditorConfig.FileChoiceUrl = CommonLinkUtility.GetFullAbsolutePath(FileChoice.GetUrlForEditor);
                }
            }
            else
            {
                _linkToEdit = _editByUrl
                                  ? CommonLinkUtility.GetFullAbsolutePath(FilesLinkUtility.GetFileWebEditorExternalUrl(fileUri, file.Title))
                                  : CommonLinkUtility.GetFullAbsolutePath(FilesLinkUtility.GetFileWebEditorUrl(file.ID));
                if (Request.DesktopApp())
                {
                    _linkToEdit += "&desktop=true";
                }

                if (FileConverter.MustConvert(_configuration.Document.Info.File))
                {
                    _editByUrl = true;
                }
            }

            var actionAnchor = Request[FilesLinkUtility.Anchor];

            if (!string.IsNullOrEmpty(actionAnchor))
            {
                _configuration.EditorConfig.ActionLinkString = actionAnchor;
            }
        }
Beispiel #11
0
        public static void Main(string[] args)
        {
            bool   verbose           = false;
            bool   help              = false;
            bool   examples          = false;
            bool   encrypt           = false;
            bool   decrypt           = false;
            bool   sign              = false;
            bool   verifySignature   = false;
            bool   version           = false;
            bool   action            = false;
            bool   unmerge           = false;
            bool   merge             = false;
            bool   newKey            = false;
            bool   passwordProtected = false;
            int    keySize           = 2048;
            string passwd            = string.Empty;

            var argsValue = new Dictionary <string, string>();

            var opts = new OptionSet
            {
                // action
                { "d|decrypt", "decrypts the encrypted data, requires private key \n[ACTION]",
                  v => { decrypt = v != null; action = true; } },
                // action
                { "e|encrypt", "encrypts the data, if used with -s merge signature to encrypted file \n[ACTION]",
                  v => { encrypt = v != null; action = true; } },
                // action
                { "h|help", "show this message and exit \n[ACTION]",
                  v => { help = v != null; action = true; } },
                { "k|key=", "key to use",
                  v => argsValue.Add("key", v) },
                { "m|merge", "merge signature with another file, use --signaturefile, warns if no key was specified\n[ACTION]",
                  v => { merge = true; action = true; } },
                // action
                { "n|newkey", "generates a new RSA Key, default size is 2048bits, exports as .pem files by default \n[ACTION]",
                  v => { newKey = true; action = true; } },
                { "o|output=", "path to output encrypted files",
                  v => argsValue.Add("output", v) },
                { "p|password", "when generating/using a new key use this flag to set password. when using this flag must always be a private key.",
                  v => passwordProtected = true },
                // action
                { "s|sign", "signs data, requires private key \n[ACTION]",
                  v => { sign = v != null; action = true; } },
                { "t|target=", "file or directory to be encrypted, decrypted or to verify its signature if directory encrypts all file from that directory",
                  v => argsValue.Add("target", v) },
                { "u|unmerge", "unmerge signature from file, requires public key used in signature, use --hashalg to identify wich hashing algorithm was used and verify signature (if none was specified uses default: SHA256)\n[ACTION]",
                  v => { unmerge = true; action = true; } },
                // action
                { "v|verifysignature", "verify if signed data is trustworthy \n[ACTION], use --target for signed data and --signaturefile for signature file",
                  v => { verifySignature = v != null; action = true; } },
                { "x|examples", "show specific examples \n[ACTION]",
                  v => { examples = v != null; action = true; } },
                { "hashalg=", "type of hashing algorithm, examples: SHA1, SHA256. default value is SHA256",
                  v => _hashAlg = v },
                { "keyfilename=", "when generating a new key use this to choose file name, default is \"key\"",
                  v => argsValue.Add("keyfilename", v) },
                { "keysize=", "when generating key use this to choose its size, minimum size is 384 and maximum is 16384, key size must be in increments of 8 bits.",
                  (int v) => keySize = v },
                { "signaturefile=", "signature file generated based on encrypted file",
                  v => argsValue.Add("signaturefile", v) },
                { "verbose", "increase debug message verbosity",
                  v => verbose = v != null },
                // action
                { "version", "shows version \n[ACTION]",
                  v => { version = v != null; action = true; } },
            };

            try
            {
                List <string> extra   = opts.Parse(args);
                string        keyPath = argsValue.ContainsKey("key") ? argsValue["key"] : null;

                // show help when no args, not defined opts
                //   missing action option, show help
                //   when key is null and is not newkey/merge
                if (help || args == null || extra?.Count > 0 || !action ||
                    (string.IsNullOrWhiteSpace(keyPath) && !newKey && !merge))
                {
                    ShowHelp(opts);
                    return;
                }

                if (examples)
                {
                    ShowExamples(opts);
                    return;
                }

                if (version)
                {
                    var assembly = Assembly.GetEntryAssembly().GetName();
                    Console.WriteLine($"v{assembly.Version}");
                    return;
                }

                Console.WriteLine($"[*] Starting {_exeName}...");

                var output = argsValue.ContainsKey("output") ? argsValue["output"] : Environment.CurrentDirectory;
                _hashAlg = string.IsNullOrWhiteSpace(_hashAlg) ? "SHA256" : _hashAlg.ToUpper();

                EncryptionKeyPair key = default;

                if (passwordProtected)
                {
                    Console.Write("[*] Encrypted Key Password: ");
                    while (true)
                    {
                        var cKey = Console.ReadKey(true);
                        if (cKey.Key != ConsoleKey.Backspace && cKey.Key != ConsoleKey.Enter &&
                            cKey.Key != ConsoleKey.Escape && cKey.KeyChar != '\0')
                        {
                            passwd += cKey.KeyChar;
                        }
                        else if (cKey.Key == ConsoleKey.Backspace && passwd.Length > 0)
                        {
                            passwd = passwd[0..^ 1];