2012-05-30 124 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變量