Как преобразовать SecureString в систему.Струна?


все оговорки о необеспечении вашей SecureString путем создания системы.Строка из него в сторону, как это можно сделать?

Как я могу конвертировать обычную систему.Безопасность.SecureString к системе.Струна?

Я уверен, что многие из вас, кто знаком с SecureString, ответят, что никогда не следует преобразовывать SecureString в обычную строку .NET, потому что она удаляет все средства защиты. Я знаю. Но прямо сейчас мой программа все равно делает все с обычными строками, и я пытаюсь повысить ее безопасность, и хотя я собираюсь использовать API, который возвращает SecureString мне, я не пытается использовать это для повышения моей безопасности.

Я знаю о маршале.SecureStringToBSTR, но я не знаю, как взять этот BSTR и сделать систему.Вылезай из него.

для тех, кто может потребовать знать, почему я когда-нибудь захочу это сделать, ну, я беру пароль от пользователя и отправив его в виде сообщения html-формы для входа пользователя на веб-сайт. Так... это действительно должно быть сделано с управляемыми, незашифрованными буферами. Если бы я мог даже получить доступ к неуправляемому, незашифрованному буферу, я думаю, что мог бы писать байтовый поток в сетевом потоке и надеяться, что это сохранит пароль в безопасности на всем пути. Я надеюсь на ответ хотя бы на один из этих сценариев.

2 125

2 ответа:

использовать System.Runtime.InteropServices.Marshal класс:

String SecureStringToString(SecureString value) {
  IntPtr valuePtr = IntPtr.Zero;
  try {
    valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
    return Marshal.PtrToStringUni(valuePtr);
  } finally {
    Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
  }
}

если вы хотите избежать создания объекта управляемой строки, вы можете получить доступ к необработанным данным с помощью Marshal.ReadInt16(IntPtr, Int32):

void HandleSecureString(SecureString value) {
  IntPtr valuePtr = IntPtr.Zero;
  try {
    valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
    for (int i=0; i < value.Length; i++) {
      short unicodeChar = Marshal.ReadInt16(valuePtr, i*2);
      // handle unicodeChar
    }
  } finally {
    Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
  }
}

очевидно, вы знаете, как это побеждает всю цель SecureString, но я все равно перефразирую ее.

Если вы хотите однострочный, попробуйте это: (.NET 4 и выше только)

string password = new System.Net.NetworkCredential(string.Empty, securePassword).Password;

где securePassword-это SecureString.