2015-04-19 2 views
0

Вопрос, о котором я хотел бы обсудить.Клиент C# - защита маркеров аутентификации REST на клиентской машине

У нас есть службы REST (WCF), которые после входа в систему - маркер получен и отправлен клиенту. HTTPS, конечно, определен.

каждый запрос отправляет этот токен в заголовке «Авторизация».

Дело в том, что если кто-то сбрасывает память, он сможет получить токен и использовать его по своему усмотрению.

мы можем защитить этот токен только до отправки, так как нам нужно преобразовать его в строку C#, которая не может быть явно удалена.

так, есть 2 проблемы с этим подходом:

  1. мусорным перемещается коллектор управляемых объектов, и эта строка может быть продублирована в памяти
  2. строки управляется с внутренней таблицей. они являются неизменными и не могут быть очищены по запросу.

Есть ли рекомендованный способ крепления токена? возможно, буферизация заголовков каждый запрос 1 символ за раз?

Хотел бы услышать ваши мысли.

ответ

0

Ваше сообщение немного запутанно, вы клиент/потребитель, или поставщик услуг/поставщиков?

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

Это говорит, что вы ищете, SecureString вы можете найти более подробную информацию о нем here

А вот небольшой пример того, как заставить его работать ....

public void Example() 
{ 
    SecureString secureString = ConvertToSecureString("abc"); 
    string normalString = ConvertToString(secureString); 
    Console.WriteLine (normalString); 
} 

// Secure it 
public SecureString ConvertToSecureString(string password) 
{ 
    SecureString secureString = new SecureString(); 

    foreach (char c in password.ToCharArray()) 
    { 
     secureString.AppendChar(c); 
    } 

    return secureString; 
} 

// Unsecure it 
public string ConvertToString(SecureString securePassword) 
{ 
    IntPtr unmanagedString = IntPtr.Zero; 
    try 
    { 
     unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword); 
     return Marshal.PtrToStringUni(unmanagedString); 
    } 
    finally 
    { 
     Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); 
    } 
} 

Это вероятно, стоит проверить на DPAPI в то время как вы на эту тему тоже ...

Вот один из моих полезных классов, что позволяет использовать его

public void DpapiExample() 
{ 
    // Adds a level of entropy to our encryption making our encrypted data more secure 
    string entropy = "603e0f3a0ef74faf93b5e6bc2c2f7c358107"; 
    var dpapi = new Dpapi(entropy); 

    string textToEncrypt = "I'm a secret"; 

    string encryptedText; 
    dpapi.TryEncrypt(textToEncrypt, out encryptedText); 
    Console.WriteLine ("Encrypting"); 
    Console.WriteLine (textToEncrypt); 
    Console.WriteLine (encryptedText); 

    string decryptedText; 

    dpapi.TryDecrypt(encryptedText, out decryptedText); 

    Console.WriteLine ("\r\nDecrypting"); 
    Console.WriteLine (encryptedText); 
    Console.WriteLine (decryptedText); 
} 

public class Dpapi 
{ 
    private readonly byte[] entropy; 

    public Dpapi(string entropy) 
    { 
     this.entropy = Encoding.UTF8.GetBytes(entropy); 
    } 

    public Dpapi(string entropy, Encoding encoding) 
    { 
     this.entropy = encoding.GetBytes(entropy); 
    } 

    public bool TryDecrypt(string encryptedString, out string decryptedString) 
    { 
     if (string.IsNullOrWhiteSpace(encryptedString)) 
     { 
      throw new ArgumentNullException("encryptedString"); 
     } 

     decryptedString = string.Empty; 

     try 
     { 
      byte[] encryptedBytes = Convert.FromBase64String(encryptedString); 
      byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, this.entropy, DataProtectionScope.LocalMachine); 
      decryptedString = Encoding.UTF8.GetString(decryptedBytes); 
     } 
     catch 
     { 
      return false; 
     } 

     return true; 
    } 

    public bool TryEncrypt(string unprotectedString, out string encryptedString) 
    { 
     if (string.IsNullOrWhiteSpace(unprotectedString)) 
     { 
      throw new ArgumentNullException("unprotectedString"); 
     } 

     encryptedString = string.Empty; 

     try 
     { 
      byte[] unprotectedData = Encoding.UTF8.GetBytes(unprotectedString); 
      byte[] encryptedData = ProtectedData.Protect(unprotectedData, this.entropy, DataProtectionScope.LocalMachine); 
      encryptedString = Convert.ToBase64String(encryptedData); 
     } 
     catch 
     { 
      return false; 
     } 

     return true; 
    } 
} 
+0

Привет, я обновлю - я клиент. HTTPS уже определен по умолчанию. поэтому я боюсь, что кто-то сбросит память. защищенная строка не поможет, поскольку она зашифрована локально и не может быть отправлена ​​на сервер ... – ArielB

+0

и о вашем втором решении DAPI - как только секрет хранится в строке C#, он уязвим для дампов памяти – ArielB

+0

As Я сказал, что если вы скомпрометированы сервером, то меньше всего вы беспокоитесь о дампах памяти, это часть Microsoft Data Protection API, поэтому технически это не мое решение. Большинство этих файлов cookie, которые вы видите в обратном направлении из решений ASP.NET, сводятся к DPAPI. Как клиент, вы не можете многое сделать. Если пользовательская машина скомпрометирована, то это действительно ее конец, независимо от того, что вы попробуете, кто-то определил достаточно, найдет его. То есть если у меня достаточно контроля над машиной, чтобы сделать дамп памяти, мне будет достаточно, чтобы отменить прокси-сервер с помощью поддельных сертификатов и по-прежнему сделать SSL бесполезным. –

Смежные вопросы