Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.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#中的securestring。最简单的方法是迭代源字符串,并一次向安全字符串追加一个字符,如下所示: var secure = new SecureString(); foreach (char c in textbox1.Text) { secure.AppendChar(c); } 发明一次,重复使用很多。创建一个简单的扩展方法来扩展字符串基类,并将其存储在某个静态实用程序类中 using System.Security; /// <su

我希望在文本框中输入的文本转换为c#中的securestring。

最简单的方法是迭代源字符串,并一次向安全字符串追加一个字符,如下所示:

var secure = new SecureString();
foreach (char c in textbox1.Text)
{
    secure.AppendChar(c);
}

发明一次,重复使用很多。创建一个简单的扩展方法来扩展字符串基类,并将其存储在某个静态实用程序类中

using System.Security;

/// <summary>
/// Returns a Secure string from the source string
/// </summary>
/// <param name="Source"></param>
/// <returns></returns>
public static SecureString ToSecureString(this string source)
{
    if (string.IsNullOrWhiteSpace(source))
        return null;
    else
    {
        SecureString result = new SecureString();
        foreach (char c in source.ToCharArray())
            result.AppendChar(c);
        return result;
    }
}

将其用于文本框上的事件处理程序:

private void textbox1_TextChanged(object sender, EventArgs e)
    {
    SecureString newSecureTextBox = new SecureString();
        foreach (char c in textbox1.Text.ToCharArray())
        {
        newSecureTextBox.AppendChar(c);
        }
    }

通常将变量调用为
newSecureTextBox

您应该将SecureString设置为只读。因此,代码应该如下所示:

static class SecureStringExtensions
{
    public static string ToUnsecureString(this SecureString secureString)
    {
        if (secureString == null) throw new ArgumentNullException("secureString");

        var unmanagedString = IntPtr.Zero;
        try
        {
            unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
            return Marshal.PtrToStringUni(unmanagedString);
        }
        finally
        {
            Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
        }
    }

    public static SecureString ToSecureString(this string unsecureString)
    {
        if (unsecureString == null) throw new ArgumentNullException("unsecureString");

        return unsecureString.Aggregate(new SecureString(), AppendChar, MakeReadOnly);
    }

    private static SecureString MakeReadOnly(SecureString ss)
    {
        ss.MakeReadOnly();
        return ss;
    }

    private static SecureString AppendChar(SecureString ss, char c)
    {
        ss.AppendChar(c);
        return ss;
    }
}

可能有点晚了,但您也可以通过这种方式将SecureString转换为String

using System.Security;
.
.
.
/// <summary>
/// Converts String to SecureString
/// </summary>
/// <param name="input">Input in String</param>
/// <returns>Input in SecureString</returns>
public SecureString String2SecureString(String input) {
    SecureString _output = new SecureString();
    input.ToCharArray().ToList().ForEach((q) => _output.AppendChar(q));
    return _output;
}

我很惊讶没有人会想到SecureString构造函数会将指针指向char数组

public static SecureString ToSecureString(this string source)
{
    char[] charArray = source.ToCharArray();
    unsafe
    {
        fixed (char* chars = charArray)
        {
            return new SecureString(chars, charArray.Length);
        }
    }
}

请注意,此代码仅适用于
/unsafe
编译器选项。要设置此选项,请转到“项目属性”、“生成”选项卡并选中“允许不安全代码”复选框。

几乎相同,但更短:

SecureString secureString = new SecureString();
textbox1.Text.ToCharArray().ForEach(c => secureString.AppendChar(c));


在输入密码时,PasswordBox和SecurePassword属性不是比TextBox更合适吗?如果密码存储为文本框的字符串属性,则使用SecureString不会真正起作用。。。另一方面,PasswordBox在内部使用SecureString(或类似的)。正如其他人所指出的那样,google在这里领先。考虑到SO是这些东西的一个很好的资源,我们都先点击这里。一旦有人问起这个问题,让人们回到谷歌是没有建设性的。对于谷歌人来说,我在评论中找到的最简洁的答案是:
var output=new SecureString();input.ToList().ForEach(output.AppendChar)
。请注意,在转换为SecureString之前,将数据保存在普通字符串中比使用SecureString更重要。如果字符串为null或空白,则我将返回空的
SecureString
,以表示null或空的
SecureString
NullReferenceExceptions
可能很残酷。请注意,在转换为SecureString之前,将数据保存在一个普通字符串中胜过使用SecureString的全部意义。Google在这里领先。互联网上关于谷歌的答案是可以想象到的最循环的事情。如果这个问题已经被问到了,那就另当别论了(我肯定是的)。我是唯一一个对最常见的
SecureString
用例需要for循环感到困惑的人吗?@PéterTörök确实如此。但是,像使用SqlCredential参数的SqlConnection构造函数这样的东西除了将密码作为SecureString传递外别无选择-因此必须以这种方式使用不安全的SecureString。@JoeDyndale,最好将
SqlCredential
参数保存在
My.Settings
(应用程序设置/Config文件)中,加密设置文件时。根据微软的说法,无论如何都不要使用密码编码,它在部署后可以通过一些工具恢复。你不需要
.tocharray()
,所以只要
input.ToList().ForEach(q=>\u output.AppendChar(q))
Wow不知道:)@knguyen或者更好:
input.ToList().ForEach(_output.AppendChar)对代码的一个小调整是在抛出ArgumentNullExceptions时使用'nameof(securestring)'和'nameof(unsecureString)'。在我的实现中,我将lambda用于AppendChar和MakeReadOnly,但这只是个人口味酱;)这是有用的。在我自己的版本中进行了一系列小的清理,但我不知道
Marshal.SecureStringToGlobalAllocUnicode
谢谢好主意,但我想你是指
LostFocus
,而不是
TextChanged
。每次按下一个键时,TextChanged事件都会触发,因此每次都会重新生成,就像他们试图键入击键一样。为什么
.ToCharArray()
?您可以从
.Text
中获取字符,但没有找到此选项!它在Visual Studio 2017的何处?有什么用?@wpcoder你有什么样的项目?Windows Universal、Windows Classic Desktop或其他什么?Windows窗体,我指的是如何在vs 2017中添加
/unsafe
,还有什么好处?@wpcoder在VS2017中添加
/unsafe
参数的方法与早期VS版本中的方法几乎相同-右键单击
项目浏览器中的WinForms项目
,然后选择
属性
,或者双击
项目浏览器
。然后选择
Build
选项卡并选中
Allow unsafe code
复选框。这将允许您使用
不安全的{}
上下文,这是在托管代码中使用指针所必需的。谢谢@Szybki,但在VS2017 CE中找不到它,无论如何,我得到了什么好处。
public static SecureString ToSecureString(this string source)
{
    char[] charArray = source.ToCharArray();
    unsafe
    {
        fixed (char* chars = charArray)
        {
            return new SecureString(chars, charArray.Length);
        }
    }
}
SecureString secureString = new SecureString();
textbox1.Text.ToCharArray().ForEach(c => secureString.AppendChar(c));