【发布时间】:2015-05-13 22:33:26
【问题描述】:
我正在努力实现以下目标:
为了确保客户端机器尽可能少地保存敏感数据(在 SecureString 中):
- 将字节数组固定到包含敏感字符串 (SecureString) 的 BSTR 的内存中
- 使用 WCF 逐字节传输敏感数据(每次发送时清除每个字节)
- 在收到所有内容后,服务器需要将字节解码并重新转换为字符串
我非常关心编码 - 我知道 C# 将字符串数据保存为 UTF-16,但是在执行以下操作时可能无法很好地解释它吗?:
- 客户端机器转换为 BSTR -> 转换为字节 -> 通过线路发送 (WCF)
- 服务器获取 BSTR 数组,并将其转换回字符串
我应该担心编码吗? 谢谢!
=== 编辑 - 可能的解决方案===
在咨询了 EBrown 之后,他发现微软使用了以下 BOM: https://msdn.microsoft.com/en-us/library/windows/desktop/dd374101%28v=vs.85%29.aspx
要转换为 BSTR 字节,我使用以下方法(内部稍作更改): https://stackoverflow.com/a/25190648/1845545
而且,由于 C# 使用 UTF-16 编码,我将使用以下方法将其转换回来:Encoding.Unicode.GetString(bt);
【问题讨论】:
-
所以为了让
SecureString更“安全”,你要在网络上公开它吗? WCF 通信如何保护?为什么要逐个字符地发送字符串而不是单个字符串?你所做的一切都带有“内部”安全的警报气味...... -
@RemusRusanu 2 answers:如果你在内存中持有一个 C# 字符串 - 它只有在 CLR 感觉像它时才会被清理(C# 执行字符串实习),所以你的密码被暴露了。这就是为什么我需要一个字节一个字节。关于网络 - 我使用的是 HTTPS。唯一的问题是我想尽可能短的将密码保存在内存中。仅在通过网络发送时将其暴露,然后将其清除。两台机器的字节顺序都应该与它们的 Windows 相同。
-
一旦数据进入 WCF,您就会失去控制。你不能再清除字节了。它现在在内部 WCF 缓冲区中。你在和风车搏斗。实际上没有人在读取您的进程内存。如果他们可以,你已经失去了。将开发时间投入到其他地方,以使应用程序更加安全并具有真正的安全性。
-
@usr - 我们已经有一种方法可以使整个数据在传输过程中不驻留在内存中 - 所以我们很清楚。只要我尽可能地保护密码,我就没有丢失。如果您所说的是正确的,那么 SecureString 就没有任何价值。我只问编码。就是这样。
-
确实,SecureString 几乎没有任何价值。您认为在什么具体情况下它会对您有所帮助?您希望攻击者读取您的记忆吗?