C# 将字节数组转换为SecureString

C# 将字节数组转换为SecureString,c#,security,type-conversion,azure-keyvault,securestring,C#,Security,Type Conversion,Azure Keyvault,Securestring,从字节数组创建安全字符串(unicode编码)的最佳方法是什么? 我想将解密后的DEK密钥存储在内存中,解密过程由Azure.KeyVault(api)执行,结果生成字节数组 var keyBytes = client.DecryptAsync(url, keyName, keyVersion, algorithm, encryptedKeyBytes).GetAwaiter().GetResult().Result; 我已经创造了类似的东西,但我并不为此感到骄傲 var secureKey

字节数组
创建
安全字符串
(unicode编码)的最佳方法是什么? 我想将解密后的DEK密钥存储在内存中,解密过程由Azure.KeyVault(api)执行,结果生成字节数组

var keyBytes = client.DecryptAsync(url, keyName, keyVersion, algorithm, encryptedKeyBytes).GetAwaiter().GetResult().Result;
我已经创造了类似的东西,但我并不为此感到骄傲

var secureKey = new SecureString();
var secureKeyCharArray = Encoding.Unicode.GetChars(keyBytes);

for (int i = 0; i < keyBytes.Length; i++)
{
    keyBytes[i] = 0;
}

for (int i = 0; i < secureKeyCharArray.Length; i++)
{
    secureKey.AppendChar(secureKeyCharArray[i]);
    secureKeyCharArray[i] = (char)0;
}

secureKey.MakeReadOnly();

我不知道出于生产目的使用封送处理类是否合适。

最明显的问题是:

.GetAwaiter().GetResult().Result;
你几乎不应该那样做<代码>等待更可取:

var keyBytes = await client.DecryptAsync(url, keyName, keyVersion,
                                         algorithm, encryptedKeyBytes);
使用
.GetAwaiter().GetResult().Result可能导致硬死锁。更一般地说,只有当您知道结果已完成时(通过检查
IsCompleted
,或者因为您等待),才应尝试访问结果



至于其他方面:这真的取决于你的目标是什么;请注意,yes
SecureString
string
更安全,但它实际上并不是严格意义上的安全-恶意用户仍然可以将其反转。这主要是一个不便之处,并且使得内存扫描程序很难找到数据。除此之外,你所拥有的看起来还可以吗?请注意,如果要避免
AppendChar
循环,可以在
unsafe
块中使用
fixed
,并使用接受
char*
int
的构造函数,但这只是性能调整。当然,您仍然需要手动擦除源阵列。如果您选择该路径,并且密码不大,您实际上可以
stackalloc
解码成一个块,而不是将
secureKeyCharArray
作为一个数组。完成后,您仍然需要手动擦除
stackalloc
区域。

感谢您的回复,此解决方案仍在POC中,我将在解决所有安全问题后实施您的建议:)。我已经编辑了我的问题,以便在你的答案上重播,请检查这个。编辑中的代码做了不好的事情;您刚刚分配了一个托管字符串,其中包含密码——这是您很难避免的:您无法控制该字符串的生命周期;充其量,您可以希望收件人在删除内容时决定使用
不安全的
代码来擦除内容。您认为我应该以不同的方式从SecureString读取数据吗?或者我误解了你的答案。:Dit是
SecureString
的一个不幸的功能,它几乎不可被任何东西使用:)我想说的是,当你访问内容时,你需要对生命周期非常小心,仅仅返回一个字符串并不能让消费者明白这一点
var keyBytes = await client.DecryptAsync(url, keyName, keyVersion,
                                         algorithm, encryptedKeyBytes);