c# - 使用隔离存储和 ProtectedData 保存用户凭据

标签 c# serialization stream isolatedstorage

我想以一种安全的方式保存用户详细信息,所以我的目的是获取一个包含凭据的类,对其进行序列化,使用 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。可能的原因是序列化和反序列化之间的无效流或对象版本更改。

如有任何帮助,我们将不胜感激!

仅供引用,这是 ILoginCredentials 接口(interface)

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

最佳答案

好的,我发现了问题。在 GetCredentials 方法中,我有一行

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

我已经改成

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

因为我从来没有用返回值更新 protectedMemory 变量,所以我试图从仍然加密的数据中反序列化

关于c# - 使用隔离存储和 ProtectedData 保存用户凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10819265/

相关文章:

python-3.x - DRF ModelSerializer 使所有字段只读,而无需明确指定它们

c# - 从System.Web.HttpInputStream获取文件信息

c# - 使用C#读取RAR文件的内容

C#进程线程无法写入输出

c# - 服务堆栈错误构建 View 页面

java - 为 Android Password Safe 应用程序选择存储数据的最佳解决方案

java - REST Web 服务不使用我的 JsonSerializer

objective-c - CFStreamCreateBoundPair正在将4kb数据写入流,流将解析包含xml起始节点但不包含结束节点的数据

c# - 在 Visual Studio 2017 中生成 .NET Core 控制台应用程序 .exe

c# - 无法编码包含 union 的结构