我有一个用.NET Core 2.0编写的API,用于分发JSON Web令牌(JWT)。这是通过一个非常简单模型的POST请求完成的。
public class TokenRequest
{
public string Username { get; set; }
public string Password { get; set; }
}
API的详细信息并不重要 - 此处的目标是在请求完成后防止密码保留在内存中。让我们假设我可以安全地处理字符串 - 我试图解决的问题是阻止Json.NET将值赋给字符串,从而导致它被实现。
编辑:正如在答案中指出的那样,字符串不是在这里实习的,这是我的错误。即使是这样, 我担心的是密码可能会长时间在内存中以我无法控制的方式(字符串)而不是我可以控制的方式(字节数组,我可以在完成后将其清零)用它)。为清晰起见,我已删除了对实习的进一步引用。
为了测试,我一直在发出请求并使用WinDbg来确定值是否在内存中作为字符串。
我的原始模型不会按原样运行,因为它使用string
- 即使我的代码中没有任何内容引用Password
,只是它反序列化的事实最终会将字符串放入进程内存中直到收集垃圾。
知道了,我尝试了这个模型:
public class TokenRequest
{
public string Username { get; set; }
public byte[] Password { get; set; }
}
这实际上有效 - 但问题是Password
现在必须是base64编码的字符串。我无法找到原始的base64值或内存中的解码值作为字符串,这很好,但是密码base64编码是不可取的。
我已经查看了JsonTextReader
的源代码了,为什么这样做有用 - ReadAsBytes
使用char数组和字节数组读取,而不是字符串。但不幸的是,base64要求是硬编码的。
编辑:进一步考虑后,密码可能仍然存在于内存中,因为字节数组还没有GCed - 字节数组我无法控制,因为它们是Json.NET的内部
所以,我尝试了一个自定义的JsonConverter:
public class TokenRequest
{
public string Username { get; set; }
[JsonConverter(typeof(ByteConverter))]
public byte[] Password { get; set; }
}
这遇到了与原版相同的问题 - 在为转换器解析时,Json.NET最终通过字符串发送值,所以即使我的转换器的ReadJson
方法只是return new byte[] { };
方法。 1}},该值仍然可以在内存中找到。
摘要
我想在.NET Core WebAPI中获取明文字符串值,并在请求完成后将其从内存中删除,而不必等待垃圾回收。
什么样的作品,但是不受欢迎
byte[]
(警告必须是base64编码)什么不起作用
JsonConverter
(Json.NET内部使用字符串)答案 0 :(得分:0)
在运行时创建的字符串不会被实习,除非特别要求它们被实习。我认为这或许只是对实习意味着什么的混淆。我认为你更有可能只是看到尚未被垃圾收集的内存(或者还没有被重新分配)。
您可能需要查看此问题:Securing a password input in c# dotnet core console app
正如其中一些问题所提到的答案:您似乎在防范物理安全问题,而不是代码/数据安全问题。我没有在json.net上使用SecureString,但我怀疑这不会解决您的问题。