Windows Hello 淺嘗(2)

來源:互聯網
上載者:User

標籤:裝置   pair   continue   相關   null   例子   state   blog   private   

接著探索

上一篇講了一個微軟官方的Demo,這個Demo基本上已經把我們要做的事情做完了。

那麼基於這個Demo,我說下我的思路。

 

1.首先是要在介面程式中枚舉出藍牙裝置

2.為使用藍牙裝置的相關資訊建立解鎖用的Windows Hello裝置

3.當task收到解鎖事件的時候再次枚舉藍牙裝置,然後判斷每個枚舉到的藍牙裝置有沒有對應Windows Hello裝置

4. 有就使用使用這個Windows Hello裝置解鎖電腦

那這樣我先使用我的小米手環的資訊建立對應的解鎖裝置,當我的手環在附近的時候Task就能枚舉到它從而解鎖,當手環不在附近的時候Task自然就枚舉不到它,於是就不能使用Windows Hello解鎖。

 

開始實踐

關於枚舉藍牙裝置,我又在微軟的官方例子中找到了Demo

Demo地址:https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/DeviceEnumerationAndPairing

這個Demo就展示了使用DeviceWatch去枚舉裝置

DeviceWatcher m_deviceWatcher;string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };m_deviceWatcher = DeviceInformation.CreateWatcher("(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")",//m_deviceWatcher = DeviceInformation.CreateWatcher("(System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\")",                                                  requestedProperties,                                                  DeviceInformationKind.AssociationEndpoint);m_deviceWatcher.Added += DeviceWatcher_Added;m_deviceWatcher.Updated += DeviceWatcher_Updated;m_deviceWatcher.Removed += DeviceWatcher_Removed;m_deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;m_deviceWatcher.Stopped += DeviceWatcher_Stopped;m_deviceWatcher.Start();

 

這個代碼應該是一目瞭然的, 其中的關鍵就在於CreateWatcher時候使用的參數 {bb7bb05e-5972-42b5-94fc-76eaa7084d49} 能枚舉到小米手環,但是枚舉不到手機 {e0cbf06c-cd8b-4647-bb8a-263b43f0f974} 則相反,能枚舉到手機但是枚舉不到小米手環。

這個類還能枚舉到其他很多的裝置,就靠CreateWatcher的參數具體可以看官方的Demo。

下面是介面的定義,其中 DeviceInformation 和 DeviceInformationUpdate 就包含了裝置的資訊

private void DeviceWatcher_Added(DeviceWatcher Sender, DeviceInformation DeviceInfo){}private void DeviceWatcher_Updated(DeviceWatcher Sender, DeviceInformationUpdate DeviceInfoUpdate){}private void DeviceWatcher_Removed(DeviceWatcher Sender, DeviceInformationUpdate DeviceInfoUpdate){}private void DeviceWatcher_EnumerationCompleted(DeviceWatcher Sender, object e){}private void DeviceWatcher_Stopped(DeviceWatcher Sender, object e){}

 

基本屬性都有對應的變數,而我在CreateWatcher的時候附加的屬性  string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" }; 會以索引值對的形式儲存在 DeviceInformation 和 DeviceInformationUpdate 的 Properties中

 

我首先在介面程式中使用這套介面枚舉到了我的手環,基本資料是這樣的

DeviceID: BluetoothLE#BluetoothLExx:xx:xx:xx:xx:xx-xx:xx:xx:xx:xx:xx

Name: MI Band 2

 

一開始我是想直接使用 BluetoothLE#BluetoothLExx:xx:xx:xx:xx:xx-xx:xx:xx:xx:xx:xx 這個ID去建立解鎖裝置的,但是發現都失敗,實驗下來可能是只能使用GUID去建立解鎖裝置。於是我就需要把 BluetoothLE#BluetoothLExx:xx:xx:xx:xx:xx-xx:xx:xx:xx:xx:xx 也儲存起來,儲存的思路

其執行個體子中也給出了就是存在解鎖裝置的  DeviceConfigurationData  中,因為 我還要在 DeviceConfigurationData 中還要儲存解鎖用的兩個密碼,所以我乾脆就將在 DeviceConfigurationData  中儲存JSON格式的資料,專門寫了個序列化很還原序列化的類。

public class JsonData{            public string Sign { get; set; }           public string DeviceID { get; set; }            public string DeviceKey { get; set; }          public string AuthKey { get; set; }    public bool CanUnLock { get; set; }}public class CMyHelloWinJson{    public static JsonData ParesToData(string js)    {        JsonData rv = null;        try        {            JsonObject schoolObject = JsonObject.Parse(js);            if (schoolObject != null)            {                rv = new JsonData();                rv.Sign = schoolObject.GetNamedString("Sign");                rv.DeviceID = schoolObject.GetNamedString("DeviceID");                rv.DeviceKey = schoolObject.GetNamedString("DeviceKey");                rv.AuthKey = schoolObject.GetNamedString("AuthKey");                rv.CanUnLock = schoolObject.GetNamedBoolean("CanUnLock");            }        }catch(Exception e)        {            return rv;        }         return rv;    }    public static string ParesToJson(JsonData Dat)    {        JsonObject schoolObject = new JsonObject();        schoolObject.SetNamedValue("Sign", JsonValue.CreateStringValue(Dat.Sign));        schoolObject.SetNamedValue("DeviceID", JsonValue.CreateStringValue(Dat.DeviceID));        schoolObject.SetNamedValue("DeviceKey", JsonValue.CreateStringValue(Dat.DeviceKey));        schoolObject.SetNamedValue("AuthKey", JsonValue.CreateStringValue(Dat.AuthKey));        schoolObject.SetNamedValue("CanUnLock", JsonValue.CreateBooleanValue(Dat.CanUnLock));        return schoolObject.ToString();    }}

 

所以在介面中建立解鎖裝置的代碼就變成了這樣

string modelnumber = "MyHelloWin";// 隨機數轉 string 可能會丟失資訊的byte[] deviceKeyArray = new byte[32];byte[] authKeyArray = new byte[32];IBuffer deviceKey = CryptographicBuffer.CreateFromByteArray(deviceKeyArray);IBuffer authKey = CryptographicBuffer.CreateFromByteArray(authKeyArray);JsonData Dat = new JsonData();Dat.Sign = "MyHellowin";Dat.DeviceKey = System.Text.Encoding.UTF8.GetString(deviceKeyArray);Dat.AuthKey = System.Text.Encoding.UTF8.GetString(authKeyArray);Dat.DeviceID = DeviceID;Dat.CanUnLock = false;string js = CMyHelloWinJson.ParesToJson(Dat);byte[] signArry = System.Text.Encoding.UTF8.GetBytes(js);IBuffer deviceConfigData = CryptographicBuffer.CreateFromByteArray(signArry);String deviceGUId = System.Guid.NewGuid().ToString();int state = await WinHello.RegisterDeviceAsync(deviceGUId, bleDeviceDisplay.DeviceName, modelnumber, deviceConfigData, deviceKey, authKey);// 註冊SecondaryAuthenticationFactorDeviceCapabilities Capabilities = SecondaryAuthenticationFactorDeviceCapabilities.SecureStorage;SecondaryAuthenticationFactorRegistrationResult RegistrationResult = await SecondaryAuthenticationFactorRegistration.RequestStartRegisteringDeviceAsync(DervicesID,        Capabilities,        FriendlyName,        ModelNumber,        deviceKey,        authKey);if (RegistrationResult.Status == SecondaryAuthenticationFactorRegistrationStatus.Started) {    await RegistrationResult.Registration.FinishRegisteringDeviceAsync(DerviceContext);}return (int)RegistrationResult.Status;

 

介面寫好了,那麼解鎖的時候思路大致就是這樣的

先是枚舉出所有的藍牙裝置,使用和上面相同的方法。

private void DeviceWatcher_Added(DeviceWatcher Sender, DeviceInformation DeviceInfo){

  IReadOnlyList<SecondaryAuthenticationFactorInfo> deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(SecondaryAuthenticationFactorDeviceFindScope.AllUsers);
  for (int i = 0; i < deviceList.Count; i++)  {      SecondaryAuthenticationFactorInfo deviceInfo = deviceList.ElementAt(i);      byte[] combinedDataArray;      CryptographicBuffer.CopyToByteArray(deviceInfo.DeviceConfigurationData, out combinedDataArray);      string JS = System.Text.Encoding.UTF8.GetString(combinedDataArray);      JsonData Dat = CMyHelloWinJson.ParesToData(JS);      if (Dat == null)      {          continue;      }      if (String.Equals(Dat.DeviceID, DeviceInfo.DeviceID)) { // 使用這個裝置進行解鎖  } 
  }
}

 

具體解鎖的方法,上面一篇文章中有相應的介紹。或者你直接看我寫的Demo: http://git.oschina.net/alwaysking/MyHelloWin

然而,當我天真的這樣就搞定的時候,來了個晴天霹靂,因為在Task中使用DeviceWatcher枚舉裝置的時候他的回呼函數根本不會被觸發。注意我的藍牙裝置是配對的裝置。

解決方案也是有的,我們下一篇再講

 

Windows Hello 淺嘗(2)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.