У меня есть два приложения:
- приложение WPF, которое захватывает пароль с помощью элемента PasswordBox и шифрует строку C #, используя его, и
- приложение ASP.NET, которое получает тот же пароль через конфигурацию в виде открытого текста и использует его для расшифровки строки из # 1.
Приложение 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...
}
Здесь нет ошибки: показанные строки в обеих функциях действительно одинаковы, как они, ИМХО, должны быть.
И все же, переменная lengthInBytes
внутри Decrypt
отличается между приложениями. Это равно 8 в ASP.NET (где он не может расшифровать) и 4 в WPF (где обе функции работают правильно). Открытый текст тестового пароля был «test», если это имеет значение.
Причина, по которой я не показываю остальную часть кода, заключается в том, что он не имеет большого значения. Для меня очевидно, что это невозможно, пока существует эта разница, поэтому я сосредоточился на этом.
Приложение WPF захватывает SecureString
непосредственно из свойства PasswordBox.SecurePassword
. OTOH, ASP.NET создает его, вызывая AppendChar
в цикле на свежем SecureString
экземпляре. Я знаю, что это не так безопасно, но не было никакой жизнеспособной неинтерактивной альтернативы для этого сценария. Хотя это не относится к делу, я подозреваю, что это может быть частью проблемы. Я просто пока не вижу, как.
Что я пропустил?
FWIW, приложение WPF в настоящее время использует инструмент Obfuscar
в своем исполняемом файле ввода. Я еще не пытался отключить это, чтобы увидеть, если это имеет какое-либо значение.
ОБНОВЛЕНИЕ : Вот код, который я использую на стороне ASP.NET для создания SecureString
из открытого текста System.String
:
using (var secure = new SecureString())
{
for (var i = 0; i < plaintext.Length; i++)
{
secure.AppendChar(plaintext[i]);
}
return Decrypt(encrypted, secure, salt);
}