Сохранить пароль с помощью Windows Hello
Я хочу сохранить и восстановить пароль с Windows Hello
, Пользователь может выбрать во время входа в систему, если он хочет ввести свой пароль вручную, или если он хочет использовать Windows Hello
разблокировать (который затем извлекает последний использованный пароль и заполняет его для пользователя).
Если Windows Hello
правильно настроен, в документе есть два варианта использования.
Один, чтобы просто разблокировать:
UserConsentVerificationResult consentResult = await UserConsentVerifier.RequestVerificationAsync("userMessage");
if (consentResult.Equals(UserConsentVerificationResult.Verified))
{
// continue
}
и один, чтобы подписать сообщение с сервера:
var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);
if (openKeyResult.Status == KeyCredentialStatus.Success)
{
var userKey = openKeyResult.Credential;
var publicKey = userKey.RetrievePublicKey();
//the message is the challenge from the server
var signResult = await userKey.RequestSignAsync(message);
if (signResult.Status == KeyCredentialStatus.Success)
{
//the with the private key of the user signed message
return signResult.Result;
}
}
И то, и другое не очень полезно для моего варианта использования: я хочу симметричный способ хранения и восстановления пароля.
Мой вопрос вкратце:
Есть ли способ симметрично хранить данные с Windows Hello
?
соответствующие документы:
https://docs.microsoft.com/en-us/windows/uwp/security/microsoft-passport
0 ответов
Я решил эту проблему, зашифровав / расшифровав секрет, который я хотел сохранить, используя пароль, сгенерированный с помощью Windows Hello. Пароль был подписью над фиксированным сообщением.
Полный пример кода (непроверенный), чтобы проиллюстрировать мою точку зрения:
const accountId = "A ID for this key";
const challenge = "sign this challenge using Windows Hello to get a secure string";
public async Task<byte[]> GetSecureEncryptionKey() {
// if first time; we first need to create a key
if (firstTime) {
if (!await this.CreateKeyAsync()) {
return null;
}
}
// get the key using Windows Hellp
return await this.GetKeyAsync();
}
private async Task<bool> CreateKeyAsync() {
if (!await KeyCredentialManager.IsSupportedAsync()) {
return false;
}
// if app opened for the first time, we need to create an account first
var keyCreationResult = await KeyCredentialManager.RequestCreateAsync(AccountId, KeyCredentialCreationOption.ReplaceExisting);
return keyCreationResult.Status == KeyCredentialStatus.Success);
}
private async Task<byte[]> GetKeyAsync() {
var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);
if (openKeyResult.Status == KeyCredentialStatus.Success)
{
// convert our string challenge to be able to sign it
var buffer = CryptographicBuffer.ConvertStringToBinary(
challenge, BinaryStringEncoding.Utf8
);
// request a sign from the user
var signResult = await openKeyResult.Credential.RequestSignAsync(buffer);
// if successful, we can use that signature as a key
if (signResult.Status == KeyCredentialStatus.Success)
{
return signResult.Result.ToArray();
}
}
return null;
}
Полный исходный код находится на github и показывает, как я интегрировал эти концепции в приложение.
Вы можете использовать PasswordVault следующим образом для установки пароля:
private void SetPassword(string password, string userName)
{
PasswordVault myVault = new PasswordVault();
myVault.Add(new PasswordCredential("Your App ID", userName, password));
}
для удаления пароля:
private void RemovePassword(string userName)
{
PasswordVault myVault = new PasswordVault();
var password = myVault.Retrieve("Your App ID", userName);
if (password != null)
myVault.Remove(password);
}
если вы хотите использовать его с Windows Hello:
public async Task<string> SignInAsync(string userName)
{
var result = await UserConsentVerifier.RequestVerificationAsync(requestMessage);
if (result != UserConsentVerificationResult.Verified)
return null;
var vault = new PasswordVault();
var credentials = vault.Retrieve("Your App ID", userName);
return credentials?.Password;
}
это будет проверять Windows Hello, прежде чем получить доступ к значению пароля