安全地将加密的标准字符串转换为securestring

我有一个加密的标准字符串,在powershell中通过“convertfrom-securestring”创建并保存到文件中。 后来,我用C#app读取了这个加密的字符串(在相同的用户ID和同一台机器上)。 我想将此加密字符串转换为securestring对象。 在powershell中,可以使用“convertto-securestring”来完成此操作。 如何在c#中安全地做到这一点?

我知道这个答案( 我如何使用ConvertTo-SecureString ), 但它假设已使用已知密钥创建加密字符串 。 这与加密字符串是在没有密钥的情况下创建的情况不同(因此与绑定到用户ID和构造它的机器相关联。)

另请注意,在上述问题的注释中,引用了Microsoft的文档,表明在未提供密钥的情况下使用Windows数据保护API(DPAPI)。 本文( https://msdn.microsoft.com/en-us/library/ms229741(v=vs.110).aspx )展示了如何使用DPAPI,但遗憾的是,它以Microsoft文章中指定的方式使用它结果再次导致字符串在字符串对象中以明文forms出现(我们无法控制,相对于处理),因此以指示的方式使用它将是不安全的。

实际上,这实际上是这个( 如何解密通过PowerShell加密的C#中的字符串 )和我如何使用ConvertTo-SecureString中的问题的组合 。

为了记录,这段代码有效,但我不确定将解密后的字符串存储在字节数组中会出现什么问题,即使我尽快破解它:

public static unsafe SecureString MakeSecurityString(string pwd) { int lngth = pwd.Length / 2; byte[] encrypted = new byte[lngth]; for (int i = 0; i < lngth; ++i) { encrypted[i] = byte.Parse(pwd.Substring(2 * i, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); } byte[] decrypted = ProtectedData.Unprotect(encrypted, (byte[])null, DataProtectionScope.CurrentUser); lngth = decrypted.Length - 1; byte[] chr = new byte[2]; SecureString secureString = new SecureString(); for (int i = 0; i < lngth; ) { chr[0] = decrypted[i]; decrypted[i++] = 0; chr[1] = decrypted[i]; decrypted[i++] = 0; string passwd = UnicodeEncoding.Unicode.GetString(chr); secureString.AppendChar(passwd[0]); } return secureString; } 

注意将字节对从decrypted复制到chr ,然后一次应用UnicodeEncoding.Unicode.GetString一个字符的明显愚蠢。 如果我们这样做的话

 string passwd = UnicodeEncoding.Unicode.GetString(decrypted); for (int i = 0; i < passwd.Length; ++i) { secureString.AppendChar(passwd[i]); } 

然后我们将“解密”字符串放入一个字符串对象中,它可以在内存中挂起 – 我们无法控制。 上面的代码避免了这一点。 我不清楚将字节数组保留并将其归零可以保证内存中没有副本。 有人可以对此发表评论吗?

我不知道是否有本地C#方法来执行此操作,但如果没有,您可以始终回退使用运行空间来执行powershell管道并只使用cmdlet。

如果保持运行空间打开,重复执行将非常快。