Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在持久化到磁盘时是否必须加密SecureString?_C#_Securestring - Fatal编程技术网

C# 在持久化到磁盘时是否必须加密SecureString?

C# 在持久化到磁盘时是否必须加密SecureString?,c#,securestring,C#,Securestring,对于C#console应用程序,我需要在应用程序设置中保留密码,但当我创建类型为System.Security.SecureString的设置时,设置本身将从纯文本配置文件中删除。由于我再也看不到原始值,所以无法验证数据在保存时是否仍然加密 SecureString是最好的方法还是应该使用ProtectedData简单地加密字符串 --编辑-- 下面是我用来验证SecureString是否可以持久化的测试代码 [global::System.Configuration.Appli

对于C#console应用程序,我需要在应用程序设置中保留密码,但当我创建类型为
System.Security.SecureString
的设置时,设置本身将从纯文本配置文件中删除。由于我再也看不到原始值,所以无法验证数据在保存时是否仍然加密

SecureString
是最好的方法还是应该使用
ProtectedData
简单地加密字符串

--编辑-- 下面是我用来验证
SecureString
是否可以持久化的测试代码

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public global::System.Security.SecureString Password
        {
            get
            {
                return ((global::System.Security.SecureString)(this["Password"]));
            }
            set { this["Password"] = value; }
        }

        static void Main(string[] args)
        {
            PersistPassword("A-Test-Password");
            Console.WriteLine(ReadPassword());
            Console.ReadLine();
        }

        static void PersistPassword(string Password)
        {
            SecureString ss = new SecureString();
            Password.ToCharArray().ToList().ForEach(ss.AppendChar);
            Settings.Default.Password = ss;
        }

        static string ReadPassword()
        {
            SecureString ss = Settings.Default.Password;
            IntPtr ptr = Marshal.SecureStringToCoTaskMemUnicode(ss);
            return Marshal.PtrToStringUni(ptr);
        }
正如美国所说

初始化实例或修改值时,SecureString实例的值将使用底层平台支持的机制自动保护

如果您希望提供一种机制,在securestring中存储密码后使其保持只读,则可以对其调用方法
MarkAsReadonly()


出于持久性目的,您还可以散列
SecureString
,并为其创建salt。您可以将盐回收,以备日后使用,例如比较。请查看使用salt over
Securestring

的代码片段。您无法保存使用Securestring加密的数据。密钥保存在内存中,并且只在程序处于活动状态时有效。SecureString是本机函数的包装器

如果您需要加密数据的持久性(比您的程序存在的时间更长),则需要数据保护API(DPAPI)及其函数,该函数通过ProtectedData类向C#用户公开

SecureString具有短暂的优点;适用于:

  • 密码
  • 信用卡号码
  • 社会保险号码
当它们被你的程序使用时-然后被删除

DPAPI更适合长期存储。但要注意保护级别,选择适合您需要的保护级别:

  • 只能由我解密
  • 仅可在此电脑上解密
  • 只能由域中的任何人解密
如果您需要能够传输到不同站点或不同域的加密:CryptProtectData不适合您

四级
  • CryptProtectMemory(.NET中的SecureString):仅在进程的内存中有用
  • CryptProtectData(.NET中的ProtectedData):加密一组数据,您可以将其存储在任何您喜欢的地方(内存、注册表、硬盘),但您必须自己存储
  • CredWrite:使用CryptProtectData加密密码,并将其存储在Windows密码保险库中(开始)→ 凭证管理器)
  • CredUIPromptForCredentials/CredUIConfirmCredentials:提示用户输入密码,对其进行加密,并将其保存在密码保管库中(开始→ 凭证管理器)使用CredWrite

我认为这根本行不通。您可以使用
BCrypt
散列您的密码。安全字符串只是一个类,它不允许您使用字符串。实际上,您只能使用
封送
指针
使用它。如果您希望将密码保存在app.config中并从应用程序中使用它,我想您可以这样做。如果是这样,请注意,我将添加一些示例代码。我可以成功地持久化并读取设置文件中的SecureString,并且由于它没有给出异常,我只能假设它仍然是加密的(或至少是序列化的)。。它从同一进程中读取,因为它仍然在内存中,但是如果退出并重新启动,您会发现字符串是空的。