using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; namespace System.Security { /// /// 为键/值对提供简单的安全存储 /// /// /// 每个平台使用平台提供的本机API来安全存储数据: /// /// /// iOS:数据存储在KeyChain中。有关SecAccessible的其他信息 /// /// /// Android:加密密钥存储在密钥库中,加密数据存储在命名的共享首选项容器中 /// /// /// UWP:数据使用 DataProtectionProvider 加密并存储在命名的 ApplicationDataContainer /// /// /// AspNetCore:数据使用仓储实现 /// /// /// 注意:在运行 Android 23(6.0/M)以下的 Android 设备上,KeyStore中没有AES可用。作为最佳实践,此API将生成存储在KeyStore中的RSA/ECB/PKCS7Padding密钥对(KeyStore中这些较低的API级别支持的唯一类型),用于包装运行时生成的AES密钥。这个包装好的密钥存储在首选项中 /// public interface IStorage { /// /// 获取给定键的值 /// /// 键 /// 如果键不存在,则返回null string? Get(string key); /// Task GetAsync(string key); /// /// 存储给定键的值 /// /// 键 /// 值 void Set(string key, string? value); /// Task SetAsync(string key, string? value); /// /// 移除给定键的键/值对 /// /// 要移除的键 /// 如果删除了键值对,则返回true bool Remove(string key); /// Task RemoveAsync(string key); [return: MaybeNull] public static TValue Deserialize(string? strValue) { return Serializable.DMPB64U(strValue); } public static string? Serialize(TValue value) { string? strValue; if (value is string str) { strValue = str; } else { if (value == null) { strValue = null; } else { strValue = Serializable.SMPB64U(value); } } return strValue; } /// [return: MaybeNull] public TValue Get(string key) { var strValue = Get(key); var value = Deserialize(strValue); return value; } #nullable disable /// public async Task GetAsync(string key) { var strValue = await GetAsync(key); var value = Deserialize(strValue); return value; } #nullable restore public void Set(string key, TValue value) { var strValue = Serialize(value); Set(key, strValue); } public Task SetAsync(string key, TValue value) { var strValue = Serialize(value); return SetAsync(key, strValue); } public static IStorage Instance => DI.Get(); } }