在Swing中,密码字段具有getPassword()(返回char[])方法而不是通常getText()(返回String)方法.同样,我遇到了一个不使用String来处理密码的建议.
为什么String在密码方面会对安全构成威胁?使用感觉不方便char[].
我试图了解.NET的SecureString的目的.来自MSDN:
System.String类的一个实例都是不可变的,当不再需要时,不能以编程方式安排垃圾收集; 也就是说,实例在创建后是只读的,并且无法预测实例何时从计算机内存中删除.因此,如果String对象包含敏感信息(如密码,信用卡号或个人数据),则使用该信息后可能会显示该信息,因为您的应用程序无法从计算机内存中删除该数据.
SecureString对象类似于String对象,因为它具有文本值.但是,SecureString对象的值会自动加密,可以修改,直到您的应用程序将其标记为只读,并且可以通过应用程序或.NET Framework垃圾收集器从计算机内存中删除.
初始化实例或修改值时,SecureString实例的值会自动加密.您的应用程序可以呈现实例不可变,并通过调用MakeReadOnly方法防止进一步修改.
自动加密是最大的收益吗?
为什么我不能说:
SecureString password = new SecureString("password");
Run Code Online (Sandbox Code Playgroud)
代替
SecureString pass = new SecureString();
foreach (char c in "password".ToCharArray())
pass.AppendChar(c);
Run Code Online (Sandbox Code Playgroud)
我错过了SecureString的哪个方面?
所以这个类似乎很少使用:SecureString.它至少从2.0开始就存在,并且有一些SO问题,但我想我会问自己的具体问题:
我有一个LoginForm; 带有用户名和(掩码)密码字段的简单WinForms对话框.当用户同时输入并单击"登录"时,信息将传递到执行一层键扩展的注入认证类,然后散列一半拉伸键进行验证,而另一半是加密用户的对称密钥帐户数据.完成所有这些操作后,将关闭loginForm,处理身份验证器类,然后系统继续加载主窗体.非常标准的东西,可能比标准的哈希 - 密码和比较更多一些,但是在我的情况下,简单的哈希密码将通过以明文形式存储用户数据而被打败,因为该数据包括第三个的凭证 - 派对系统(我们都知道人们如何重用密码).
这是第一个问题; 我如何使用SecureString从密码文本框中检索密码,而不是通过文本框的Text属性将其公开为普通的System.String?我假设有一种方法可以访问由CLR类包装的Textbox的非托管GDI窗口,并使用Marshal类提取文本数据.我只是不知道怎么样,而且我似乎无法找到好的信息.
这是第二个问题; 一旦我将密码作为SecureString,我如何从System.Security.Crypto命名空间将其传递给哈希提供程序?我的猜测是我使用Marshal.SecureStringToBSTR(),然后Marshal.Copy()从返回的IntPtr返回到一个字节数组.然后我可以调用Marshal.ZeroBSTR()来清理非托管内存,一旦我有哈希,我可以用Array.Clear()将托管数组清零.如果有一种更简洁的方法可以让我完全控制内存的任何托管副本的生命周期,请告诉我们.
第三个问题; 这一切真的是必要的,还是在托管内存环境中System.String固有的不安全性有点过分了?在操作系统考虑将应用程序交换到虚拟内存之前很久,任何用于存储密码(加密或其他方式)的内容都应该超出范围并且在前往垃圾收集器的路上(允许在交换文件后从交换文件中嗅探密码)硬关机的电脑).冷启动攻击是一种理论上的可能性,但实际上,这有多常见?更大的问题是现在解密的用户数据,它在整个应用程序生命周期中作为用户的一部分而挂起(因此将成为使用SecureStrings的主要候选者,因为除了几个基本用法之外,它们保持相当休眠状态).
我正在寻找Java相当于.NET的SecureString.aspx.是否有这样的实施在2018年?
OWASP实现并不完全相同,因为它只是一个普通的char数组.虽然.NET等价物提供了额外的功能,例如从/向非托管内存获取实例的能力以及加密.
我知道普通的Java模式传递密码,char[]并Arrays.fill()在使用后用零做.但它需要在char[]所有时间内构建一个简单的实用程序类.
我正在为Windows 10制作一个客户端应用程序.我有一个问题,我想开源我的代码,但让其他人看不到API密钥.这是我的源文件的相关部分:
private const string ApiKey = "YOUR_API_KEY";
Run Code Online (Sandbox Code Playgroud)
我想把它变成
private const string ApiKey = "THE_ACTUAL_API_KEY";
Run Code Online (Sandbox Code Playgroud)
什么时候编译.我该怎么做呢?
编辑:对不起任何含糊之处; 我问如何防止GitHub上的源代码的查看者看到字符串,而不必在本地构建期间更改它.此问题与加密无关.
Checkmarx 报告了一个关于密码属性字符串的堆检查漏洞。此属性是模型的一部分,在提交登录表单时绑定。在 ASP.NET MVC 中有没有办法使用除常规字符串以外的任何其他内容来绑定表单中的密码?
到目前为止,我已经尝试将属性类型更改为 char [] 或 SecureString,但在这种情况下,表单不会将数据绑定到它。
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Run Code Online (Sandbox Code Playgroud) 在我的一次代码审查中,我偶然发现了一个有趣的SecureString. 从逻辑上讲,将值隐藏在内存中是有好处的,但我的理解IConfiguration是,当通过ConfigurationBuilder副本注入和构建时,内存中已经存在以供使用。因此,SecureString虽然隐藏了明文值,但配置访问会自动否定密文。
我的想法是否正确,真的价值是不安全的,甚至不应该使用,SecureString因为它开始不安全 -
public class Sample
{
private readonly SecureString secret;
public Sample(IConfiguration configuration) => secret = new NetworkCredentials(String.Empty,
configuration.GetSection("Api:Credentials")["secret"]).SecurePassword;
}
Run Code Online (Sandbox Code Playgroud) c# ×4
security ×3
.net ×2
java ×2
securestring ×2
.net-core ×1
api ×1
api-key ×1
asp.net ×1
asp.net-mvc ×1
char ×1
encryption ×1
passwords ×1
string ×1