我尝试使用Mi Band 2连接和验证应用,但在最后一步(发送加密密钥并接收成功的身份验证响应)后,我收到错误响应。 第一,第二和第三步是成功的,没有例外。 以下是所有身份验证代码。
认证级别为1的主要认证方法(通知带有所需的触摸响应)
检查authCharacteristic的新更新并等待来自band的新响应。有2个,3个和4个级别的身份验证。
加密到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();
}
此处控制台中的所有调试消息:
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
答案 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();
我认为我的问题出现在错误的加密代码中。