Answers:
你不知道 使用SecureString对象的全部原因是避免创建一个字符串对象(该对象将被加载到内存中并以纯文本格式保存,直到进行垃圾回收为止)。但是,可以通过附加字符将字符添加到SecureString。
var s = new SecureString();
s.AppendChar('d');
s.AppendChar('u');
s.AppendChar('m');
s.AppendChar('b');
s.AppendChar('p');
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('d');
*****
AppendChar
直到运行时才执行,所以那些字符仍然可以从IL中读取,对吗?也许一些编译时混淆也可能会有所帮助……也就是说,如果您正在硬编码密码。
还有一种在SecureString
和之间进行转换的方法String
。
1.字符串到SecureString
SecureString theSecureString = new NetworkCredential("", "myPass").SecurePassword;
2. SecureString转换为String
string theString = new NetworkCredential("", theSecureString).Password;
这是链接
SecureString
如果代码使用string
想要保护的值创建对象,则使用a没有意义。其目的SecureString
是避免在托管内存中使用字符串,因此攻击者检查该内存可以发现您要隐藏的值。由于NetworkCredential
您要调用的构造函数需要一个字符串,所以这不是走的路...当然,您的代码是在SecureString之间来回转换的简便方法,但是使用它使您的代码与使用简单的代码一样安全string
SecureString
在处理某些库时我们仍然需要使用。坦白说,如果有人正在积极扫描应用程序的内存,那么您已经迷路了。即使您正确使用了SecureString(我从未见过),也将提取其他有价值的数据。
下面的方法有助于将字符串转换为安全字符串
private SecureString ConvertToSecureString(string password)
{
if (password == null)
throw new ArgumentNullException("password");
var securePassword = new SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
securePassword.MakeReadOnly();
return securePassword;
}
这是一个便宜的linq技巧。
SecureString sec = new SecureString();
string pwd = "abc123"; /* Not Secure! */
pwd.ToCharArray().ToList().ForEach(sec.AppendChar);
/* and now : seal the deal */
sec.MakeReadOnly();
我把它扔在那里。为什么?
您不能只是将所有字符串更改为安全字符串,而突然您的应用程序是“安全的”。安全字符串的设计目的是使字符串尽可能长时间地保持加密,并且仅在很短的时间内解密,并在对其执行操作后擦除内存。
我冒昧地说,在担心保护应用程序字符串之前,您可能需要处理一些设计级别的问题。向我们提供有关您的尝试操作的更多信息,我们可能会更好地提供帮助。
没有花哨的linq,没有手工添加所有字符,只是简单明了:
var str = "foo";
var sc = new SecureString();
foreach(char c in str) sc.appendChar(c);
var sc = new SecureString(); foreach(char c in "foo") sc.appendChar(c);
我只是想指出,所有的人说:“这不是点SecureString
”,很多人问这个问题的可能是在何处,无论出于何种原因,合理与否,他们的应用程序并不特别在意有密码的临时副本以GC可用字符串的形式位于堆上,但他们必须使用仅接受的APISecureString
对象。因此,您有一个不需要关心的应用程序密码是否在堆上,也许仅用于内部使用,并且仅存在于密码中,因为基础网络协议要求使用该密码,并且您发现存储密码的字符串不能用于例如设置远程PowerShell运行空间-但是没有简单,直接的一线内容即可创建SecureString
所需的内容。这是一个小麻烦-但可能值得的,以确保真正的应用程序做需要SecureString
做不可试探作者使用System.String
或System.Char[]
中介机构。:-)
如果您想将a string
到a 的转换压缩SecureString
为一条LINQ
语句,则可以将其表示为以下形式:
var plain = "The quick brown fox jumps over the lazy dog";
var secure = plain
.ToCharArray()
.Aggregate( new SecureString()
, (s, c) => { s.AppendChar(c); return s; }
, (s) => { s.MakeReadOnly(); return s; }
);
但是,请记住,使用LINQ
不会提高此解决方案的安全性。它具有与从string
到任何转换相同的缺陷SecureString
。只要原始文件string
保留在内存中,数据就容易受到攻击。
就是说,以上语句可以提供的是将的创建SecureString
,其初始化与数据保持在一起,并最终将其锁定以防止修改。
以下2个扩展应该可以解决问题:
对于char
阵列
public static SecureString ToSecureString(this char[] _self)
{
SecureString knox = new SecureString();
foreach (char c in _self)
{
knox.AppendChar(c);
}
return knox;
}
而对于 string
public static SecureString ToSecureString(this string _self)
{
SecureString knox = new SecureString();
char[] chars = _self.ToCharArray();
foreach (char c in chars)
{
knox.AppendChar(c);
}
return knox;
}
感谢John Dagg的AppendChar
推荐。
12345
……那是白痴在他的行李上所拥有的那种东西!”