无法验证Mi Band 2

时间:2018-04-24 14:27:01

标签: c# encryption uwp bluetooth-lowenergy aes

我尝试使用Mi Band 2连接和验证应用,但在最后一步(发送加密密钥并接收成功的身份验证响应)后,我收到错误响应。 第一,第二和第三步是成功的,没有例外。 以下是所有身份验证代码。

  1. 认证级别为1的主要认证方法(通知带有所需的触摸响应)

  2. 检查authCharacteristic的新更新并等待来自band的新响应。有2个,3个和4个级别的身份验证。

  3. 加密到AES / ECB / NoPadding加密(我也尝试过AesCbc,但结果相同)。

    public async Task<bool> Authenticate()
    {
        var authCharacteristic = await Gatt.GetCharacteristicByServiceUuid(new Guid("0000FEE1-0000-1000-8000-00805F9B34FB"), new Guid("00000009-0000-3512-2118-0009af100700"));
        // Subscribe to notifications
        await authCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
    
        // Level 1
        Debug.WriteLine("Level 1 started");
        byte[] secretKey = new byte[] { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 };
        List<byte> sendKey = new List<byte>();
        sendKey.Add(1);
        sendKey.Add(8);
        sendKey.AddRange(secretKey);
    
        if (await authCharacteristic.WriteValueAsync(sendKey.ToArray().AsBuffer()) == GattCommunicationStatus.Success)
        {
            Debug.WriteLine("Level 1 success");
            authCharacteristic.ValueChanged += authCharacteristic_ValueChanged;
        }
    
        return isAuthed;
    }
    
    private async void authCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
    {
        var authCharacteristic = await Gatt.GetCharacteristicByServiceUuid(new Guid("0000FEE1-0000-1000-8000-00805F9B34FB"), new Guid("00000009-0000-3512-2118-0009af100700"));
    
        if (sender.Uuid.ToString() == "00000009-0000-3512-2118-0009af100700")
        {
            Debug.WriteLine("Received characteristic value: " + args.CharacteristicValue.ToArray().ToList()[0]);
            Debug.WriteLine("Received SendKey: " + args.CharacteristicValue.ToArray().ToList()[1]);
            Debug.WriteLine("Received Status: " + args.CharacteristicValue.ToArray().ToList()[2]);
    
            var request = args.CharacteristicValue.ToArray().ToList();
    
            byte authResponse = 0x10;
            byte authSendKey = 0x01;
            byte authRequestRandomAuthNumber = 0x02;
            byte authRequestEncryptedKey = 0x03;
            byte authSuccess = 0x01;
            byte authFail = 0x04;
    
            if (request[0] == authResponse && request[1] == authSendKey && request[2] == authSuccess)
            {
                Debug.WriteLine("Level 2 started");
                List<byte> authNumber = new List<byte>();
                authNumber.Add(0x02);
                authNumber.Add(0x08);
    
                if (await authCharacteristic.WriteValueAsync(authNumber.ToArray().AsBuffer()) == GattCommunicationStatus.Success)
                    Debug.WriteLine("Level 2 success");
            }
            else if (request[0] == authResponse && request[1] == authRequestRandomAuthNumber && request[2] == authSuccess)
            {
                Debug.WriteLine("Level 3 started");
    
                List<byte> randomKey = new List<byte>();
                List<byte> relevantResponsePart = new List<byte>();
                var responseValue = args.CharacteristicValue.ToArray();
    
                for (int i = 0; i < responseValue.Count(); i++)
                {
                    if (i >= 3)
                        relevantResponsePart.Add(responseValue[i]);
                }
    
                randomKey.Add(0x03);
                randomKey.Add(0x08);
                randomKey.AddRange(Encrypt(relevantResponsePart.ToArray()));
    
                if (await authCharacteristic.WriteValueAsync(randomKey.ToArray().AsBuffer()) == GattCommunicationStatus.Success)
                    Debug.WriteLine("Level 3 success");
            }
            else if (request[0] == authResponse && request[1] == authRequestEncryptedKey && request[2] == authSuccess)
            {
                // Can't reach this code. Last byte is 4 (error). 
                Debug.WriteLine("Auth completed");
                isAuthed = true;
            }
        }
    }
    
    public byte[] Encrypt(byte[] data)
    {
        byte[] secretKey = new byte[] { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 };
        string aesKey = Convert.ToBase64String(secretKey);
        IBuffer key = Convert.FromBase64String(aesKey).AsBuffer();
        SymmetricKeyAlgorithmProvider algorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcb);
        CryptographicKey ckey = algorithmProvider.CreateSymmetricKey(key);
    
        IBuffer buffEncrypt = CryptographicEngine.Encrypt(ckey, data.AsBuffer(), null);
        return buffEncrypt.ToArray();
    }
    
  4. 此处控制台中的所有调试消息:

    Connected to MI Band 2
    Level 1 started
    Level 1 success
    Received characteristic value: 16
    Received SendKey: 1
    Received Status: 1
    Level 2 started
    Level 2 success
    Received characteristic value: 16
    Received SendKey: 2
    Received Status: 1
    Level 3 started
    Level 3 success
    Received characteristic value: 16
    Received SendKey: 3
    Received Status: 4
    

1 个答案:

答案 0 :(得分:0)

当我在Encryption()

中更改字符串时问题解决了
        byte[] secretKey = new byte[] { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45 };
        IBuffer key = secretKey.AsBuffer();

我认为我的问题出现在错误的加密代码中。