我有两个应用程序:
WPF应用程序能够很好地解密字符串,而ASP.NET应用程序则不行。我已经确保了两个应用程序中用于加密/解密的明文和盐类是相同的。
下面是两个应用程序共享的相关代码:
string Encrypt(string value, SecureString password, string salt)
{
var temp = Marshal.SecureStringToBSTR(password);
var lengthInBytes = Marshal.SizeOf(temp);
// The rest of the encryption code...
}
string Decrypt(string value, SecureString password, string salt)
{
var temp = Marshal.SecureStringToBSTR(password);
var lengthInBytes = Marshal.SizeOf(temp);
// The rest of the decryption code...
}这里没有错误:这两个函数中显示的行实际上是相同的,它们,IMHO应该是一样的。
然而,在不同的应用程序之间,lengthInBytes变量在Decrypt中是不同的。在ASP.NET (解密失败)下,它等于8;在WPF下,它等于4(这两个函数都正确工作)。测试密码明文是" test ",如果这很重要的话。
我之所以没有展示其余的代码,是因为它并不重要。很明显,在这种差异存在的情况下,它不可能起作用,所以这就是我所关注的问题。
WPF应用程序直接从SecureString属性捕获PasswordBox.SecurePassword。OTOH,ASP.NET通过在一个新的SecureString实例的循环中调用AppendChar来构建它。我知道这并不安全,但是没有任何可行的非交互的替代方案。虽然这与问题无关,但我怀疑这可能是问题的一部分。我只是还不知道该怎么做。
我错过了什么?
FWIW,WPF应用程序目前正在其入口可执行文件上使用Obfuscar工具。我还没有试着禁用它,看看它是否有任何不同。
UPDATE:下面是我在ASP.NET端使用的代码,用于从纯文本System.String创建SecureString
using (var secure = new SecureString())
{
for (var i = 0; i < plaintext.Length; i++)
{
secure.AppendChar(plaintext[i]);
}
return Decrypt(encrypted, secure, salt);
}发布于 2018-05-06 20:17:02
您不正确地使用Marshal.SizeOf试图获取字符串长度,但这将返回IntPtr结构大小。此外,我建议使用unicode编码,以避免由于系统的编码而对数据进行任何更改:
string Encrypt(string value, SecureString password, string salt)
{
try
{
var temp = Marshal.SecureStringToGlobalAllocUnicode(password);
var lengthInBytes = sizeof(char) * password.Length;
// The rest of the encription code...
}
finally
{
//Cleanup
Marshal.ZeroFreeGlobalAllocUnicode(temp);
}
}
string Decrypt(string value, SecureString password, string salt)
{
try
{
var temp = Marshal.SecureStringToGlobalAllocUnicode(password);
var lengthInBytes = sizeof(char) * password.Length;
// The rest of the decryption code...
}
finally
{
//Cleanup
Marshal.ZeroFreeGlobalAllocUnicode(temp);
}
}永远记住将内存为零并释放它,否则SecureString的目的就会失败。
https://stackoverflow.com/questions/50203111
复制相似问题