C# 如何将字符串显式转换为securestring
我希望在文本框中输入的文本转换为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
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));