简体   繁体   English

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

[英]Save user credentials using isolated storage and ProtectedData

I want to save user details in a secure way so my intention is to take a class that contains the credentials, serialize it, encrypt it using protectedData and then save this new encrypted data in isolated storage. 我想以一种安全的方式保存用户详细信息,因此我的目的是采用一个包含凭据的类,对其进行序列化,使用protectedData对其进行加密,然后将该新的加密数据保存在隔离的存储中。 I have the following save method 我有以下保存方法

    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();
        }
    }

This bit of code seems to work no problem 这段代码似乎没有问题

Then I have the code that restores to object 然后我有还原为对象的代码

    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;
        }
    }

When I attempt to deserialize the object in the ToCredentials method I get the following error 当我尝试在ToCredentials方法中反序列化对象时,出现以下错误

Binary stream 'n' does not contain a valid BinaryHeader. 二进制流“ n”不包含有效的BinaryHeader。 Possible causes are invalid stream or object version change between serialization and deserialization. 可能的原因是序列化和反序列化之间无效的流或对象版本更改。

Any help would be gratefully appreciated! 任何帮助将不胜感激!

FYI this is the ILoginCredentials interface 仅供参考,这是ILoginCredentials接口

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

Ok I found the problem. 好的,我发现了问题。 In the GetCredentials method I had the line 在GetCredentials方法中,

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

I have changed this to 我已将其更改为

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

Becuase I was never updating the protectedMemory variable with the return value I was attempting to deserialize from the still encrypted data 因为我从来没有用我试图从仍然加密的数据中反序列化的返回值来更新protectedMemory变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM