【问题标题】:How to securely store key in Xamarin?如何在 Xamarin 中安全地存储密钥?
【发布时间】:2016-06-29 04:47:26
【问题描述】:

假设,我想在移动设备上安全地在本地保存几个键值条目。看起来,我可以使用 Android 的 KeyStore 和 iOS 的 Keychain 并将ILocalStorage 实现注入 PCL。但是,我还没有找到任何使用这两者的例子。你能告诉我如何做到这一点或提供资源吗?或者也许告诉我一个更好的方法来实现我想要实现的目标?提前致谢。

【问题讨论】:

  • 如果数据量不大,你可以使用sharedpreference,否则sqlite是跨平台的,如果你有大数据集,你可以使用它。

标签: android ios xamarin xamarin.forms


【解决方案1】:

您好,请参考https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/general/store-credentials/中的示例 它在 android 中使用 kestore,在 iOS 中使用 keychain

除此之外我已经在 MVVM cross 中完成了这个实现

public class PersistantStorageHelper<T>
    {
        IMvxFileStoreAsync _mvxFileStoreAsync;
        IMvxFileStore _mvxFileStore;
        EDEngine bcEngine = new EDEngine(new AesEngine(), Encoding.UTF8);
        string currentkey_temp_dev = "AthulHarikumar00";//This static key is not being used it is a just a place holder

        public PersistantStorageHelper() {
            this._mvxFileStore = Mvx.Resolve<IMvxFileStore>();
            this._mvxFileStoreAsync = Mvx.Resolve<IMvxFileStoreAsync>();
            bcEngine.SetPadding(new Pkcs7Padding());
            currentkey_temp_dev = Constants.PassPhrase.Substring(4, 12)+"Road";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public async Task<T> GetPersistantObject(T obj)
        {
            var fileName = (typeof(T).ToString().Replace(".", "_"));
           var x= await GetPersistantObject(obj, fileName);
            return x;
        }
        /// <summary>
        /// If object exists returns the object else saves a plain object and returns it
        /// </summary>
        /// <param name="obj">empty placeholder object</param>
        /// <returns>Filesystem object</returns>
        public async Task<T> GetPersistantObject( T obj,string fileName) {

            List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
            fileName = _mvxFileStore.NativePath(fileName);

            if (!files.Contains(fileName))
            {
                var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

                objJson= bcEngine.Encrypt(objJson, currentkey_temp_dev);
                await _mvxFileStoreAsync.WriteFileAsync(fileName,objJson);
            }
            else {
                try
                {

                    var temp = await _mvxFileStoreAsync.TryReadTextFileAsync(fileName);
                    var str = bcEngine.Decrypt(temp.Result, currentkey_temp_dev);
                    obj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
                }
                catch(Exception e) {
                    var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

                    objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
                    await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);
                }
            }

            return obj;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public async Task<T> SetPersistantObject(T obj)
        {
            var fileName = _mvxFileStore.NativePath(typeof(T).ToString().Replace(".", "_"));
            var temp = await SetPersistantObject(obj, fileName);
            return temp;

        }
        /// <summary>
        /// Saves object to persistant storage with encryption
        /// </summary>
        /// <param name="obj">object to be stored</param>
        /// <returns>Saved object</returns>
        public async Task<T> SetPersistantObject(T obj,string fileName)
        {

            List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
             fileName = _mvxFileStore.NativePath(fileName);


                var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
            await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);



            return obj;
        }
    }

在初始创建时将密码短语作为 GUID 注入保存在 Keystore/Keychain/Vault 中,这将加密数据并使用密码短语存储您提供的任何对象

【讨论】:

  • 正是我需要的谢谢。我会在尝试您的解决方案后尽快接受此答案。
  • 不可以,如果需要的话可以加锁写
【解决方案2】:

你有几个选择。

平方精简版。此选项是跨平台的,如果您有大量数据,则效果很好。您还可以获得事务支持和异步支持的额外好处。此处有详细记录:https://github.com/oysteinkrog/SQLite.Net-PCL

在 Xamarin.Forms 中还实现了 Application properties,它允许简单的键值对数据。 您必须调查并找出最适合您需求的路线。

就安全性而言,这取决于您在每台设备上放置数据的位置。默认情况下,Android 将应用程序数据存储在安全的应用程序文件夹中(如果您是 root 用户,则不是那么安全)。 iOS根据不同的需求有几种不同的数据存储文件夹。

【讨论】:

    猜你喜欢
    • 2014-10-18
    • 2015-07-04
    • 1970-01-01
    • 2015-11-24
    • 2014-06-24
    • 2018-03-16
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多