2012-05-30 3 views
2

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

public bool SaveCredentials(ILoginCredentials credentials) 
    { 
     try 
     { 
      //CredentialStorage implements ILoginCredentials 
      CredentialStorage storage = new CredentialStorage(credentials); 
      byte[] lastEncryptedData = ToByteArray(storage); 
      lastEncryptedData = ProtectedData.Protect(lastEncryptedData, AditionalEntropy, DataProtectionScope.CurrentUser); 

      IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); 
      IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("ExternalSSOProvider", FileMode.Create, 
                       FileAccess.Write, isoStore); 
      isoStream.Write(lastEncryptedData, 0, lastEncryptedData.Length); 
      isoStream.Close(); 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 

    private static byte[] ToByteArray(object source) 
    { 
     var formatter = new BinaryFormatter(); 
     using (var stream = new MemoryStream()) 
     { 
      formatter.Serialize(stream, source); 
      return stream.ToArray(); 
     } 
    } 

Этот бит кода, кажется, не работает никакой проблемы,

Тогда у меня есть код, который восстанавливает объект

private CredentialStorage GetCredentials() 
    { 
     try 
     { 
      IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); 
      if (isoStore.FileExists("ExternalSSOProvider")) 
      { 
       using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("ExternalSSOProvider", FileMode.Open, isoStore)) 
       { 
        using (StreamReader reader = new StreamReader(stream)) 
        { 
         using(MemoryStream ms = new MemoryStream()) 
         { 
          reader.BaseStream.CopyTo(ms); 
          byte[] protectedMemory = ms.ToArray(); 
          ms.Close(); 
          ProtectedData.Unprotect(protectedMemory, AditionalEntropy, DataProtectionScope.CurrentUser); 
          return ToCredentials(protectedMemory); 
         } 
        } 
       } 
      } 
     } 
     catch (Exception) 
     { 
      return null; 
     } 
     return null; 
    } 

    private static CredentialStorage ToCredentials(byte[] source) 
    { 
     var formatter = new BinaryFormatter(); 
     using (var stream = new MemoryStream(source)) 
     { 
      var x = formatter.Deserialize(stream); //My exception occurs here 
      return x as CredentialStorage; 
     } 
    } 

При попытке десериализации объекта в метод ToCredentials получает следующую ошибку:

Двоичный поток 'n' не содержит допустимого BinaryHeader. Возможными причинами являются неправильное изменение версии потока или объекта между сериализацией и десериализацией.

Любая помощь будет с благодарностью оценена!

FYI Это интерфейс ILoginCredentials

public interface ILoginCredentials 
{ 
    string Username { get; } 
    string Password { get; } 
} 
+1

Пожалуйста, не храните пароль в любой восстанавливаемой манере. Хешируйте их и храните хэш. Я знаю, что не отвечает на ваш вопрос и за это я извиняюсь. –

+0

Вы пробовали Flush перед тем, как закрыть метод SaveCredentials? –

+0

Да, я пробовал это, но все равно не работал – John

ответ

1

Ok Я нашел проблему. В методе GetCredentials я имел линию

ProtectedData.Unprotect(protectedMemory, AditionalEntropy, DataProtectionScope.CurrentUser); 

Я изменил это

protectedMemory = ProtectedData.Unprotect(protectedMemory, AditionalEntropy, DataProtectionScope.CurrentUser); 

потому что я никогда не обновляю переменную protectedMemory с возвращаемым значением я пытал десериализацию из еще зашифрованных данных

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