2015-01-30 2 views
1

В приложении Asp.net MVC 5 у меня есть SecureString, переданная в мое представление через модель. Теперь я хотел бы написать содержимое этого SecureString в поток Response без необходимости сначала преобразовать его в строку. Как я могу это достичь?Как написать содержимое SecureString в поток Response?

+4

Использование SecureString в контексте HTTP не имеет никакого смысла. Класс существует только для предотвращения того, что строка находится в памяти вашего приложения на виду. Как только вы захотите передать его по HTTP, он _must_ станет простой строкой. – CodeCaster

+0

Я знаю, что не будет такой вещи, как 100% -ная безопасность, но я бы хотел как можно больше уменьшить поверхность атаки. Поэтому я передаю данные в качестве SecureString внутри моего приложения, и теперь, когда мне действительно нужно показать его конечному пользователю, я хочу записать его непосредственно в поток Response, а не сначала преобразовать его в строку и записать его в поток. –

+2

API HTTP HTTP не предоставляет этого. Единственный вход, который вы получаете в тело ответа HTTP, находится в виде потока открытого текста, в котором вам нужно написать строки или байты, которые вы хотите передать. Поэтому, чтобы записать их в ответ, они должны быть открытым текстом. – CodeCaster

ответ

0

Это расширение HtmlHelper, с которым я столкнулся. Я уверен, что он может быть улучшен, но он достигает моей цели записи SecureString в поток Response без его представления в виде строки.

public static class SecureStringHelpers 
{ 
    public static void WriteSecureStringToResponse(this HtmlHelper helper, SecureString secureString) 
    { 
     if (secureString != null) 
     { 
      IntPtr unmanagedString = IntPtr.Zero; 

      var secureByteArray = new byte[2]; 

      try 
      { 
       unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString); 

       var offset = 0; 
       var endOfString = false; 

       do 
       { 
        secureByteArray[0] = Marshal.ReadByte(unmanagedString, offset); 
        offset++; 
        secureByteArray[1] = Marshal.ReadByte(unmanagedString, offset); 
        offset++; 

        if (!(secureByteArray[0] == 0 && secureByteArray[1] == 0)) 
        { 
         helper.ViewContext.Writer.Write(System.BitConverter.ToChar(secureByteArray, 0)); 
        } 
        else 
        { 
         endOfString = true; 
        } 

       } while (!endOfString); 
      } 
      finally 
      { 
       Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); 
       secureByteArray[0] = 0; 
       secureByteArray[1] = 0; 
      } 
     } 
    } 
}