static async Task <(int err, byte[] sig)> VerifyUser(string key_name, string contentToSign) { if (await KeyCredentialManager.IsSupportedAsync() == false) { await(new MessageDialog("KeyCredentialManager not supported")).ShowAsync(); return(ERR_VERIFY_HELLO_NOT_SUPPORTED, null); } var key = await KeyCredentialManager.OpenAsync(key_name); if (key.Status != KeyCredentialStatus.Success) { return(CredentialStatusToExitCode(key.Status), null); } var buf = CryptographicBuffer.ConvertStringToBinary(contentToSign, BinaryStringEncoding.Utf8); var signRes = await key.Credential.RequestSignAsync(buf); if (signRes.Status != KeyCredentialStatus.Success) { return(CredentialStatusToExitCode(key.Status), null); } byte[] sig; CryptographicBuffer.CopyToByteArray(signRes.Result, out sig); return(0, sig); }
/// <summary> /// Check if a ms passport account exists /// </summary> /// <exception cref="UserCancelledException"></exception> /// <exception cref="UserPrefersPasswordException"></exception> /// <exception cref="UnknownException"></exception> /// <exception cref="AggregateException"></exception> /// <param name="accountId">The id of the account to check</param> /// <returns>true if the account exists</returns> public static bool PassportAccountExists(string accountId) { // Try to get the account Task <KeyCredentialRetrievalResult> task = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId)); // Check the result switch (task.Result.Status) { case KeyCredentialStatus.Success: // The account was found return(true); case KeyCredentialStatus.NotFound: // The account was not found return(false); case KeyCredentialStatus.UserCanceled: // The operation was cancelled by the user throw new UserCancelledException(); case KeyCredentialStatus.UserPrefersPassword: // The user prefers a password throw new UserPrefersPasswordException(); default: // An unknwon error occurred throw new UnknownException(); } }
public async Task <Result> SignInWithWindowsHelloAsync() { string userName = AppSettings.Current.UserName; if (IsWindowsHelloEnabled(userName)) { var retrieveResult = await KeyCredentialManager.OpenAsync(userName); if (retrieveResult.Status == KeyCredentialStatus.Success) { var credential = retrieveResult.Credential; var challengeBuffer = CryptographicBuffer.DecodeFromBase64String("challenge"); var result = await credential.RequestSignAsync(challengeBuffer); if (result.Status == KeyCredentialStatus.Success) { UpdateAuthenticationStatus(true); return(Result.Ok()); } return(Result.Error("Windows Hello", $"Cannot sign in with Windows Hello: {result.Status}")); } return(Result.Error("Windows Hello", $"Cannot sign in with Windows Hello: {retrieveResult.Status}")); } return(Result.Error("Windows Hello", "Windows Hello is not enabled for current user.")); }
public const int ERR_CREAT_KEY_EXISTS = 170; // Avoid reserved exit codes of UNIX static async Task <(int err, string pubKey)> CreatePublicKey(string key_name) { int err; var createRes = await KeyCredentialManager.RequestCreateAsync(key_name, KeyCredentialCreationOption.FailIfExists); IBuffer pubKey; if (createRes.Status == KeyCredentialStatus.CredentialAlreadyExists) { var existing = await KeyCredentialManager.OpenAsync(key_name); if (existing.Status != KeyCredentialStatus.Success) { return(ERR_CREAT_FAIL, null); } err = ERR_CREAT_KEY_EXISTS; pubKey = existing.Credential.RetrievePublicKey(); } else if (createRes.Status != KeyCredentialStatus.Success) { return(ERR_CREAT_FAIL, null); } else { err = 0; pubKey = createRes.Credential.RetrievePublicKey(); } var pem = String.Format("-----BEGIN PUBLIC KEY-----\n{0}\n-----END PUBLIC KEY-----\n", CryptographicBuffer.EncodeToBase64String(pubKey)); return(err, pem); }
public static async Task <bool> UnlinkAccount(string userId) { var retrieveResult = await KeyCredentialManager.OpenAsync(userId); if (retrieveResult.Status != KeyCredentialStatus.Success) { return(false); } KeyCredential userCredential = retrieveResult.Credential; string publicKeyHint = CalculatePublicKeyHint(userCredential.RetrievePublicKey()); var unlinkResult = await PlayFab.PlayFabClientAPI.UnlinkWindowsHelloAsync(new UnlinkWindowsHelloAccountRequest { PublicKeyHint = publicKeyHint }); if (unlinkResult.Error != null) { MessageDialog message = new MessageDialog($"Error while un-linking: {unlinkResult.Error.Error} {unlinkResult.Error.ErrorMessage}"); await message.ShowAsync(); } return(unlinkResult.Error == null); }
private async Task <bool> SignInWithHelloAsync() { LookupUser(); // Open the existing user key credential. KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(userId); if (retrieveResult.Status != KeyCredentialStatus.Success) { return(false); } KeyCredential userCredential = retrieveResult.Credential; // Request a challenge from the server. JsonValue jsonChallenge = await JsonRequest.Create() .AddString("userId", userId) .AddString("publicKeyHint", publicKeyHint) .PostAsync("api/Authentication/RequestChallenge"); if (jsonChallenge == null) { return(false); } // Sign the challenge using the user's KeyCredential. IBuffer challengeBuffer = CryptographicBuffer.DecodeFromBase64String(jsonChallenge.GetString()); KeyCredentialOperationResult opResult = await userCredential.RequestSignAsync(challengeBuffer); if (opResult.Status != KeyCredentialStatus.Success) { return(false); } // Get the signature. IBuffer signatureBuffer = opResult.Result; // Send the signature back to the server to confirm our identity. // The publicKeyHint tells the server which public key to use to verify the signature. JsonValue jsonResult = await JsonRequest.Create() .AddString("userId", userId) .AddString("publicKeyHint", publicKeyHint) .AddString("signature", CryptographicBuffer.EncodeToBase64String(signatureBuffer)) .PostAsync("api/Authentication/SubmitResponse"); if (jsonResult == null) { return(false); } return(jsonResult.GetBoolean()); }
private async Task <IBuffer> GetPassportAuthenticationMessage(IBuffer message, string accountId) { KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(accountId); if (openKeyResult.Status == KeyCredentialStatus.Success) { KeyCredential userKey = openKeyResult.Credential; IBuffer publicKey = userKey.RetrievePublicKey(); KeyCredentialOperationResult signResult = await userKey.RequestSignAsync(message); if (signResult.Status == KeyCredentialStatus.Success) { return(signResult.Result); } else if (signResult.Status == KeyCredentialStatus.UserCanceled) { // User cancelled the Passport PIN entry. // // We will return null below this and the username/password // sign in form will show. } else if (signResult.Status == KeyCredentialStatus.NotFound) { // Must recreate Passport key } else if (signResult.Status == KeyCredentialStatus.SecurityDeviceLocked) { // Can't use Passport right now, remember that hardware failed and suggest restart } else if (signResult.Status == KeyCredentialStatus.UnknownError) { // Can't use Passport right now, try again later } return(null); } else if (openKeyResult.Status == KeyCredentialStatus.NotFound) { // Passport key lost, need to recreate it //textblock_PassportStatusText.Text = "Microsoft Passport is almost ready!\nPlease go to Windows Settings and set up a PIN to use it."; //grid_PassportStatus.Background = new SolidColorBrush(Color.FromArgb(255, 50, 170, 207)); //button_PassportSignIn.IsEnabled = false; m_passportAvailable = false; } else { // Can't use Passport right now, try again later } return(null); }
public static async void RemovePassportAccountAsync(UserAccount account) { //Open the account with Windows Hello KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(account.Username); if (keyOpenResult.Status == KeyCredentialStatus.Success) { // In the real world you would send key information to server to unregister AuthService.AuthService.Instance.PassportRemoveUser(account.UserId); } //Then delete the account from the machines list of Passport Accounts await KeyCredentialManager.DeleteAsync(account.Username); }
/// <summary> /// Function to be called when user requests deleting their account. /// Checks the KeyCredentialManager to see if there is a Passport for the current user /// Then deletes the local key associated with the Passport. /// </summary> public static async void RemovePassportAccountAsync(Account account) { // Open the account with Passport KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(account.Username); if (keyOpenResult.Status == KeyCredentialStatus.Success) { // In the real world you would send key information to server to unregister //e.g. RemovePassportAccountOnServer(account); } // Then delete the account from the machines list of Passport Accounts await KeyCredentialManager.DeleteAsync(account.Username); }
/// <summary> /// Checks the KeyCredentialManager to see if there is a Passport for the current user and /// sends the informaton to the server to unregister it. /// /// Then deletes the local key associated with the Passport. /// </summary> private async void PassportDelete() { KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(activeAccount.Email); if (keyOpenResult.Status == KeyCredentialStatus.Success) { var userKey = keyOpenResult.Credential; var publicKey = userKey.RetrievePublicKey(); // Send key information to server to unregister it DeletePassportServerSide(); } await KeyCredentialManager.DeleteAsync(activeAccount.Email); }
/// <summary> /// Attempts to sign a message using the Passport key on the system for the accountId passed. /// </summary> /// <param name="message">The message to be signed</param> /// <param name="accountId">The account id for the Passport key we are using to sign</param> /// <returns>Boolean representing if creating the Passport authentication message succeeded</returns> private async Task <IBuffer> GetPassportAuthenticationMessage(IBuffer message, string accountId) { KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(accountId); if (openKeyResult.Status == KeyCredentialStatus.Success) { KeyCredential userKey = openKeyResult.Credential; IBuffer publicKey = userKey.RetrievePublicKey(); KeyCredentialOperationResult signResult = await userKey.RequestSignAsync(message); if (signResult.Status == KeyCredentialStatus.Success) { return(signResult.Result); } else if (signResult.Status == KeyCredentialStatus.UserCanceled) { // User cancelled the Passport PIN entry. // // We will return null below this and the username/password // sign in form will show. } else if (signResult.Status == KeyCredentialStatus.NotFound) { // Must recreate Passport key } else if (signResult.Status == KeyCredentialStatus.SecurityDeviceLocked) { // Can't use Passport right now, remember that hardware failed and suggest restart } else if (signResult.Status == KeyCredentialStatus.UnknownError) { // Can't use Passport right now, try again later } return(null); } else if (openKeyResult.Status == KeyCredentialStatus.NotFound) { // Passport key lost, need to recreate it } else { // Can't use Passport right now, try again later } return(null); }
/// <summary> /// 认证用户授权 /// </summary> /// <returns></returns> public static async Task <AuthenticatorState> VerifyUserAsync() { if (await CheckSupportAsync().ConfigureAwait(false)) { if (ApplicationData.Current.LocalSettings.Values["WindowsHelloPublicKeyForUser"] is string PublicKey) { KeyCredentialRetrievalResult RetrievalResult = await KeyCredentialManager.OpenAsync(CredentialName); switch (RetrievalResult.Status) { case KeyCredentialStatus.Success: { KeyCredentialOperationResult OperationResult = await RetrievalResult.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(ChallengeText, BinaryStringEncoding.Utf8)); if (OperationResult.Status == KeyCredentialStatus.Success) { var Algorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaSignPkcs1Sha256); var Key = Algorithm.ImportPublicKey(CryptographicBuffer.DecodeFromHexString(PublicKey)); return(CryptographicEngine.VerifySignature(Key, CryptographicBuffer.ConvertStringToBinary(ChallengeText, BinaryStringEncoding.Utf8), OperationResult.Result) ? AuthenticatorState.VerifyPassed : AuthenticatorState.VerifyFailed); } else { return(AuthenticatorState.UnknownError); } } case KeyCredentialStatus.NotFound: { return(AuthenticatorState.CredentialNotFound); } default: { return(AuthenticatorState.UnknownError); } } } else { return(AuthenticatorState.UserNotRegistered); } } else { return(AuthenticatorState.WindowsHelloUnsupport); } }
public static async Task <bool> GetPassportAuthenticationMessageAsync(UserAccount account) { KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(account.Username); if (openKeyResult.Status == KeyCredentialStatus.Success) { return(true); } else if (openKeyResult.Status == KeyCredentialStatus.NotFound) { if (await CreatePassportKeyAsync(account.UserId, account.Username)) { return(await GetPassportAuthenticationMessageAsync(account)); } } // Can't use Passport right now, try again later return(false); }
/// <summary> /// Checks the KeyCredentialManager to see if there is a Passport for the current user and /// sends the informaton to the server to unregister it. /// /// Then deletes the local key associated with the Passport. /// </summary> private async void PassportDelete() { KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(activeAccount.Email); if (keyOpenResult.Status == KeyCredentialStatus.Success) { var userKey = keyOpenResult.Credential; var publicKey = userKey.RetrievePublicKey(); // Send key information to server to unregister it DeletePassportServerSide(); } await KeyCredentialManager.DeleteAsync(activeAccount.Email); rootPage.NotifyUser("User " + activeAccount.Email + " deleted.", NotifyType.StatusMessage); button_Forget.IsEnabled = false; button_Forget.Content = "User Forgotten."; }
public async void Load() { try { if (await KeyCredentialManager.IsSupportedAsync()) { var result = await KeyCredentialManager.OpenAsync(Helper.AppName); if (result.Credential != null) { var signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(DeviceHelper.PackageName, BinaryStringEncoding.Utf8)); if (signResult.Status == KeyCredentialStatus.Success) { Unlock(); } else { BiometricsButton.Visibility = Visibility.Visible; } } else { var creationResult = await KeyCredentialManager.RequestCreateAsync(Helper.AppName, KeyCredentialCreationOption.ReplaceExisting); if (creationResult.Status == KeyCredentialStatus.Success) { Unlock(); } else { BiometricsButton.Visibility = Visibility.Visible; } } } else { PassText.Focus(FocusState.Keyboard); } } catch { } }
private async Task <byte[]> GetSignedKeyAsync(string keyPhrase) { var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId); if (openKeyResult.Status == KeyCredentialStatus.Success) { var userKey = openKeyResult.Credential; var buffer = CryptographicBuffer.ConvertStringToBinary( keyPhrase, BinaryStringEncoding.Utf8 ); var signResult = await userKey.RequestSignAsync(buffer); if (signResult.Status == KeyCredentialStatus.Success) { return(signResult.Result.ToArray()); } } return(null); }
public static async Task <bool> RegisterWindowsHello(string userId) { // Check if the user already exists and if so log them in. KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(userId); if (retrieveResult.Status == KeyCredentialStatus.Success) { return(await SignInWithHelloAsync(userId, retrieveResult)); } // Create the key credential with Passport APIs IBuffer publicKey = await CreatePassportKeyCredentialAsync(userId); if (publicKey != null) { // Register the public key and attestation of the key credential with the server // In a real-world scenario, this would likely also include: // - Certificate chain for attestation endorsement if available // - Status code of the Key Attestation result : Included / retrieved later / retry type if (await RegisterPassportCredentialWithServerAsync(publicKey, userId)) { // Remember that this is the user whose credentials have been registered // with the server. ApplicationData.Current.LocalSettings.Values["userId"] = userId; // Registration successful. Continue to the signed-in state. return(true); } else { // Delete the failed credentials from the device. await Util.TryDeleteCredentialAccountAsync(userId); MessageDialog message = new MessageDialog("Failed to register with the server."); await message.ShowAsync(); } } return(false); }
/// <summary> /// Attempts to sign a message using the Passport key on the system for the accountId passed. /// </summary> /// <returns>Boolean representing if creating the Passport authentication message succeeded</returns> public static async Task <bool> GetPassportAuthenticationMessageAsync(Account account) { KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(account.Username); // Calling OpenAsync will allow the user access to what is available in the app and will not require user credentials again. // If you wanted to force the user to sign in again you can use the following: // var consentResult = await Windows.Security.Credentials.UI.UserConsentVerifier.RequestVerificationAsync(account.Username); // This will ask for the either the password of the currently signed in Microsoft Account or the PIN used for Microsoft Passport. if (openKeyResult.Status == KeyCredentialStatus.Success) { // If OpenAsync has succeeded, the next thing to think about is whether the client application requires access to backend services. // If it does here you would Request a challenge from the Server. The client would sign this challenge and the server // would check the signed challenge. If it is correct it would allow the user access to the backend. // You would likely make a new method called RequestSignAsync to handle all this // e.g. RequestSignAsync(openKeyResult); // Refer to the second Microsoft Passport sample for information on how to do this. // For this sample there is not concept of a server implemented so just return true. return(true); } else if (openKeyResult.Status == KeyCredentialStatus.NotFound) { // If the _account is not found at this stage. It could be one of two errors. // 1. Microsoft Passport has been disabled // 2. Microsoft Passport has been disabled and re-enabled cause the Microsoft Passport Key to change. // Calling CreatePassportKey and passing through the account will attempt to replace the existing Microsoft Passport Key for that account. // If the error really is that Microsoft Passport is disabled then the CreatePassportKey method will output that error. if (await CreatePassportKeyAsync(account.Username)) { // If the Passport Key was again successfully created, Microsoft Passport has just been reset. // Now that the Passport Key has been reset for the _account retry sign in. return(await GetPassportAuthenticationMessageAsync(account)); } } // Can't use Passport right now, try again later return(false); }
private async void Biometrics_Click(object sender, RoutedEventArgs e) { try { var result = await KeyCredentialManager.OpenAsync(Strings.Resources.AppName); if (result.Credential != null) { var signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(Package.Current.Id.Name, BinaryStringEncoding.Utf8)); if (signResult.Status == KeyCredentialStatus.Success) { Unlock(); } else { Field.Focus(FocusState.Keyboard); } } else { var creationResult = await KeyCredentialManager.RequestCreateAsync(Strings.Resources.AppName, KeyCredentialCreationOption.ReplaceExisting); if (creationResult.Status == KeyCredentialStatus.Success) { Unlock(); } else { Field.Focus(FocusState.Keyboard); } } } catch { Field.Focus(FocusState.Keyboard); } }
public async Task <bool> AuthenticateAsync() { // Waits that the app's window gets the focus. This allows to avoid having the icon in the task bar // blinking orange when windows hello starts. It might distracts the user. await _windowFocusAwaiter.Task.ConfigureAwait(false); if (!await IsWindowsHelloEnabledAsync() .ConfigureAwait(true)) // run on the current context. { _logger.LogEvent(AuthenticateEvent, "Success == False; Windows Hello isn't enabled."); return(false); } // Get credentials for current user and app KeyCredentialRetrievalResult result = await KeyCredentialManager.OpenAsync(KeyCredentialManagerName); if (result.Credential != null) { // Prompt the user to authenticate. KeyCredentialOperationResult signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(KeyCredentialManagerName, BinaryStringEncoding.Utf8)); if (signResult.Status == KeyCredentialStatus.Success) { _logger.LogEvent(AuthenticateEvent, "Success == True"); return(true); } _logger.LogEvent(AuthenticateEvent, "Success == False"); return(false); } // No previous saved credentials found, let's create them (this will also prompt the user to authenticate). KeyCredentialRetrievalResult creationResult = await KeyCredentialManager.RequestCreateAsync(KeyCredentialManagerName, KeyCredentialCreationOption.ReplaceExisting); _logger.LogEvent(AuthenticateEvent, $"Success == {creationResult.Status == KeyCredentialStatus.Success}"); return(creationResult.Status == KeyCredentialStatus.Success); }
private static async Task <bool> AuthenticateUsingWindowsHello() { if (await KeyCredentialManager.IsSupportedAsync()) { // Get credentials for current user and app var result = await KeyCredentialManager.OpenAsync("GitIt-Hello"); if (result.Credential != null) { var signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary("LoginAuth", BinaryStringEncoding.Utf8)); return(signResult.Status == KeyCredentialStatus.Success); } // If no credentials found create one var creationResult = await KeyCredentialManager.RequestCreateAsync("GitIt-Hello", KeyCredentialCreationOption.ReplaceExisting); return(creationResult.Status == KeyCredentialStatus.Success); } return(false); }
/// <summary> /// Opens a Microsoft Key credential. /// </summary> /// <param name="credentialName">Name of the credential to be opened.</param> /// <returns>KeyCredentialRetrievalResult object with all the information.</returns> internal static async Task <KeyCredentialRetrievalResult> OpenCredential(string credentialName) { return(await KeyCredentialManager.OpenAsync(credentialName)); }
/// <summary> /// Get the public key of the windiws hello account /// </summary> /// <param name="accountId">The id of the account to use</param> /// <exception cref="UserCancelledException"></exception> /// <exception cref="AccountNotFoundException"></exception> /// <exception cref="UnknownException"></exception> /// <exception cref="AggregateException"></exception> /// <returns>A passport result, storing the public key in its buffer</returns> public static byte[] GetPublicKey(string accountId) { // Try to get the account Task <KeyCredentialRetrievalResult> task = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId)); KeyCredentialRetrievalResult retrievalResult = task.Result; // Check the KeyCredentialRetrievalResult status switch (retrievalResult.Status) { case KeyCredentialStatus.Success: // Get the user's credential KeyCredential userCredential = retrievalResult.Credential; // Get the public key IBuffer publicKey = userCredential.RetrievePublicKey(); // Copy the public key to the PassportResult's buffer CryptographicBuffer.CopyToByteArray(publicKey, out byte[] buffer); // The operation was successful return(buffer); case KeyCredentialStatus.UserCanceled: // User cancelled the Passport enrollment process throw new UserCancelledException(); case KeyCredentialStatus.NotFound: // The account was not found throw new AccountNotFoundException(); default: // An unknown error occurred throw new UnknownException(); } }
public static async Task <bool> SignInWithHelloAsync(string userId, KeyCredentialRetrievalResult retrieveResult = null) { // Open the existing user key credential. if (retrieveResult == null) { retrieveResult = await KeyCredentialManager.OpenAsync(userId); } if (retrieveResult.Status != KeyCredentialStatus.Success) { return(false); } KeyCredential userCredential = retrieveResult.Credential; string publicKeyHint = CalculatePublicKeyHint(userCredential.RetrievePublicKey()); var challengeResult = await PlayFab.PlayFabClientAPI.GetWindowsHelloChallengeAsync(new GetWindowsHelloChallengeRequest { PublicKeyHint = publicKeyHint, TitleId = PlayFab.PlayFabSettings.TitleId }); if (challengeResult.Error != null) { // TODO: Failed to get a challenge, handle the error MessageDialog message = new MessageDialog($"Error during getting challenge: {challengeResult.Error.Error}"); await message.ShowAsync(); return(false); } // Sign the challenge using the user's KeyCredential. IBuffer challengeBuffer = CryptographicBuffer.DecodeFromBase64String(challengeResult.Result.Challenge); KeyCredentialOperationResult opResult = await userCredential.RequestSignAsync(challengeBuffer); if (opResult.Status != KeyCredentialStatus.Success) { MessageDialog message = new MessageDialog("Failed to have user sign the challenge string."); await message.ShowAsync(); return(false); } // Get the signature. IBuffer signatureBuffer = opResult.Result; // Send the signature back to the server to confirm our identity. // The publicKeyHint tells the server which public key to use to verify the signature. var loginResult = await PlayFab.PlayFabClientAPI.LoginWithWindowsHelloAsync(new LoginWithWindowsHelloRequest { ChallengeSignature = CryptographicBuffer.EncodeToBase64String(signatureBuffer), PublicKeyHint = publicKeyHint }); if (loginResult.Error != null) { MessageDialog message = new MessageDialog($"Error during login: {loginResult.Error.Error}"); await message.ShowAsync(); return(false); } return(true); }
private async void Path_Auth() { // check if KeyCredentialManager can be used if (await KeyCredentialManager.IsSupportedAsync() == false) { await(new MessageDialog("KeyCredentialManager not supported")).ShowAsync(); return; } // retrieve private key for sign KeyCredentialRetrievalResult res = await KeyCredentialManager.OpenAsync("key1"); if (res.Status == KeyCredentialStatus.Success) { // // If it is present, we request sign for some data // // convert string to binary buffer var inputbuf = CryptographicBuffer.ConvertStringToBinary( "Test Data 1", BinaryStringEncoding.Utf8); // sign using retrieved private key // (Windows Hello is diplayed here !) KeyCredentialOperationResult signRes = await res.Credential.RequestSignAsync(inputbuf); //KeyCredentialAttestationResult signRes = await res.Credential.GetAttestationAsync(); /* * // get the base64 encoded data to cryptographically sign * string base64encSignature = * CryptographicBuffer.EncodeToBase64String(signRes.Result); * await (new MessageDialog(base64encSignature)).ShowAsync(); */ if (signRes.Status == KeyCredentialStatus.Success) { // ナビゲーション フレームを使用して前のページに戻ります if (this.Frame != null && this.Frame.CanGoBack) { this.Frame.GoBack(); } else if (this.Frame != null) { //this.Frame.Navigate(typeof(Browser.MainBrowser)); this.Frame.Navigate(typeof(Browser.Browser1)); } } else { // get the base64 encoded data to cryptographically sign //string base64encSignature = CryptographicBuffer.EncodeToBase64String(signRes.Result); await(new MessageDialog("キャンセルしました")).ShowAsync(); //await (new MessageDialog(base64encSignature)).ShowAsync(); } } else if (res.Status == KeyCredentialStatus.NotFound) { // // If the credential is not found, we create it. // // Create the credential // (Windows Hello is diplayed here !) KeyCredentialRetrievalResult createRes = await KeyCredentialManager.RequestCreateAsync("key1", KeyCredentialCreationOption.ReplaceExisting); if (createRes.Status == KeyCredentialStatus.Success) { // ナビゲーション フレームを使用して前のページに戻ります if (this.Frame != null && this.Frame.CanGoBack) { this.Frame.GoBack(); } else if (this.Frame != null) { //this.Frame.Navigate(typeof(Browser.MainBrowser)); this.Frame.Navigate(typeof(Browser.Browser1)); } } else { // get the base64 encoded data to cryptographically sign //string base64encSignature = CryptographicBuffer.EncodeToBase64String(signRes.Result); await(new MessageDialog("キャンセルしました")).ShowAsync(); //await (new MessageDialog(base64encSignature)).ShowAsync(); } /* * // if the status is success, retrieve the public key. * if (createRes.Status == KeyCredentialStatus.Success) * { * var pubKey = createRes.Credential.RetrievePublicKey(); * AsymmetricKeyAlgorithmProvider alg = * AsymmetricKeyAlgorithmProvider.OpenAlgorithm( * AsymmetricAlgorithmNames.RsaPkcs1); * CryptographicKey ckey = alg.ImportPublicKey(pubKey); * // for ex, CryptographicEngine.VerifySignature() using this CryptographicKey * // (This time, just showing the keysize) * var dialog = new MessageDialog(string.Format("Key size is {0}", ckey.KeySize)); * await dialog.ShowAsync(); * } */ } else { await(new MessageDialog("Unknown error !")).ShowAsync(); } }
/// <summary> /// Sign a challenge using windows hello /// </summary> /// <param name="accountId">The id of the account to use</param> /// <param name="challenge">The challenge to sign</param> /// <exception cref="SignOperationFailedException"></exception> /// <exception cref="UserCancelledException"></exception> /// <exception cref="AccountNotFoundException"></exception> /// <exception cref="UnknownException"></exception> /// <exception cref="AggregateException"></exception> /// <returns>A passport result, storing the signed challenge in its buffer</returns> public static byte[] PassportSign(string accountId, byte[] challenge) { // Try to open the account Task <KeyCredentialRetrievalResult> task = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId)); KeyCredentialRetrievalResult retrieveResult = task.Result; // Check the KeyCredentialRetrievalResult status switch (retrieveResult.Status) { case KeyCredentialStatus.Success: // Get the users credential KeyCredential userCredential = retrieveResult.Credential; // Convert the challenge to an IBuffer and sign the challenge IBuffer challengeBuffer = CryptographicBuffer.CreateFromByteArray(challenge); Task <KeyCredentialOperationResult> opTask = Task.Run(async() => await userCredential.RequestSignAsync(challengeBuffer)); KeyCredentialOperationResult opResult = opTask.Result; // Check the KeyCredentialOperationResult status if (opResult.Status == KeyCredentialStatus.Success) { // Get the signature IBuffer signatureBuffer = opResult.Result; // Copy the signature to the PassportResult's buffer CryptographicBuffer.CopyToByteArray(signatureBuffer, out byte[] buffer); // The operation was successful return(buffer); } else { // The sign operation failed throw new SignOperationFailedException(); } case KeyCredentialStatus.UserCanceled: // User cancelled the Passport enrollment process throw new UserCancelledException(); case KeyCredentialStatus.NotFound: // The account was not found throw new AccountNotFoundException(); default: // An unknown error occurred throw new UnknownException(); } }
/// <summary> /// Retrieve the password to use to open the given database /// </summary> /// <param name="databaseName">name of the database</param> /// <returns>credentials to use to open this database</returns> public async static Task <PasswordParameter> GetDatabasePasswordAsync(string databaseName) { PasswordParameter credentials = null; // Try to use Windows Hello if (SettingsViewModel.Instance.WindowsHelloEnabled && await KeyCredentialManager.IsSupportedAsync() ) { // Try to open an already generated Windows Hello credentials var passportCredentials = await KeyCredentialManager.OpenAsync(WINDOWS_HELLO_SERVICE_NAME); if (passportCredentials.Status == KeyCredentialStatus.Success) { var signRes = await passportCredentials.Credential.RequestSignAsync( CryptographicBuffer.ConvertStringToBinary("LoginAuth", BinaryStringEncoding.Utf8)); if (signRes.Status == KeyCredentialStatus.Success) { // User confirmed its identity, retrieve the credentials from the system Password Vault try { credentials = await LoadDatabasePasswordAsync(databaseName); } catch (Exception) { // Prompt for credentials, then store them PasswordParameter password = await ShowPasswordDialogAsync(databaseName); StoreDatabasePassword(databaseName, password); credentials = password; } } else if (signRes.Status == KeyCredentialStatus.UserCanceled) { // User cancelled the credential throw new TaskCanceledException(); } } else { // No credentials available, need to create it var passportCredentialCreation = await KeyCredentialManager.RequestCreateAsync(WINDOWS_HELLO_SERVICE_NAME, KeyCredentialCreationOption.FailIfExists); if (passportCredentialCreation.Status == KeyCredentialStatus.Success || passportCredentialCreation.Status == KeyCredentialStatus.CredentialAlreadyExists) { // Prompt for credentials, then store them PasswordParameter password = await ShowPasswordDialogAsync(databaseName); StoreDatabasePassword(databaseName, password); credentials = password; } else if (passportCredentialCreation.Status == KeyCredentialStatus.UserCanceled) { // User cancelled the credential throw new TaskCanceledException(); } } } if (credentials == null) { // No Windows Hello, use standard password credentials = await ShowPasswordDialogAsync(databaseName); } return(credentials); }