2012-05-30 47 views
2

我想以安全的方式保存用户详细信息,因此我的意图是采取包含凭证的类,将其序列化,使用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

您在SaveCredentials方法中关闭之前是否尝试了Flush? –

+0

是的,我试过,但仍然没有工作 – John

回答

1

好吧,我发现这个问题。在GetCredentials方法我行

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

我已经改变了这

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

监守我从来没有对返回值我试图从静止加密数据

反序列化更新protectedMemory变量