// 미밴드 인증 async public void Authenticate(OnAuthHandler callback = null) { GattDeviceServicesResult servicesResult = await manager.Device.GetGattServicesForUuidAsync(new Guid(ATS_UUID)); if (servicesResult.Status == GattCommunicationStatus.Success && servicesResult.Services.Count > 0) { GattDeviceService service = servicesResult.Services[0]; GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsForUuidAsync(new Guid(ATC_UUID)); if (characteristicsResult.Status == GattCommunicationStatus.Success && characteristicsResult.Characteristics.Count > 0) { GattCharacteristic characteristic = characteristicsResult.Characteristics[0]; // Enable notification GattCommunicationStatus status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); if (status == GattCommunicationStatus.Success) { characteristic.ValueChanged += (GattCharacteristic sender, GattValueChangedEventArgs args) => { var reader = DataReader.FromBuffer(args.CharacteristicValue); byte[] messageType = new byte[3]; reader.ReadBytes(messageType); if (messageType[1] == 0x01) // Request random number { if (messageType[2] == 0x01) { manager.Write(sender, new byte[] { 0x02, 0x08 }); } else { callback.Invoke(this, false); service.Dispose(); } } else if (messageType[1] == 0x02) // Get random number { byte[] number = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(number); // Encrypt number byte[] encNumber; using (Aes aes = Aes.Create()) { aes.Key = _authKey; aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); // Constant iv, bad :( using (MemoryStream stream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(number, 0, number.Length); cryptoStream.FlushFinalBlock(); encNumber = stream.ToArray(); } } } // Send encrypted number using (var stream = new MemoryStream()) { stream.Write(new byte[] { 0x03, 0x08 }, 0, 2); stream.Write(encNumber, 0, encNumber.Length); manager.Write(characteristic, stream.ToArray()); } } else if (messageType[1] == 0x03) { if (messageType[2] == 0x01) { callback.Invoke(this, true); } else { callback.Invoke(this, false); service.Dispose(); } } }; } // Define auth secret key byte[] hash = new SHA256Managed().ComputeHash(Guid.NewGuid().ToByteArray()); _authKey = hash.Take(16).ToArray(); // Send key it to device using (var stream = new MemoryStream()) { stream.Write(new byte[] { 0x01, 0x08 }, 0, 2); stream.Write(_authKey, 0, _authKey.Length); manager.Write(characteristic, stream.ToArray()); } } } }