在 UWP 应用程序中安全存储访问令牌的位置?

Where to store access token securely in UWP application?

本地存储不是存储令牌的正确位置。但是 this 博客 post 说 LocalCache 通常是正确的位置。如果我使用 DPAPI 存储在 LocalCache 中,这是否足够安全?

PasswordVault 是存储它的好地方吗?

我如何安全地存储令牌,以便在该应用程序之外无法访问令牌?

Where to store access token securely in UWP application?

一般来说,我们经常使用 ApplicationData.LocalSettings class 存储访问令牌,将设置容器放置在本地应用程序数据存储中。您可以像下面这样使用它。

var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;

// Create a simple setting.
localSettings.Values["accesstoken"] = token;

// Read data from a simple setting.
Object value = localSettings.Values["accesstoken"];

if (value == null)
{
    // No data.
}
else
{
    // Access data in value.
}

如果您想安全地存储访问令牌。 Windows 运行时提供 PasswordVault class 来安全地存储凭据。有关更多信息,请参阅此 document.

我肯定会建议在 PasswordVault 中存储访问令牌等机密信息,因为 LocalSettings 未加密并且可以从 AppData 中的应用程序包文件夹中轻松访问。

虽然PasswordVault有点奇怪API,但是你还是可以很方便的用它来存储token:

var passwordVault = new PasswordVault();
passwordVault.Add(new PasswordCredential("Resource", "UserName", accessToken));

在您的情况下,您很可能只关心访问令牌,因此“资源”和“用户名”可能只是任意常量。检索令牌也很容易:

//find credentials in the store            
PasswordCredential? credential = null;

try
{
   // Try to get an existing credential from the vault.
   credential = _passwordVault.Retrieve("Resource", "UserName");
}
catch (Exception)
{
   // When there is no matching resource an error occurs, which we ignore.
}
credential?.RetrievePassword();
return credential?.Password;

注意 try..catch 的用法。这是因为如果未找到给定的 resource/user 名称组合,保险库将抛出(当用户手动删除系统凭据管理器中的条目时甚至可能发生这种情况。

PasswordVault 的另一个优点是凭据在设备之间同步(尽管此功能可能会在未来版本中消失)。