it-swarm.com.de

Private vs öffentliche Adressen in Bluetooth Low Energy auf Android

Ein Bluetooth-Gerät mit niedrigem Energieverbrauch wird durch seine Adresse eindeutig identifiziert (in der Android-API wird dies als MAC-Adresse bezeichnet und als durch Doppelpunkte getrennte Hex-Werte, z. B. 11: aa: 22: bb: 33: cc).

Um jedoch eine BLE-Adresse eindeutig zu identifizieren, müssen Sie wissen, ob es sich um eine öffentliche oder eine private Adresse handelt. Im Wesentlichen sind 49 Bits erforderlich, um eine Adresse zu identifizieren, nicht 48.

Zufallsadressen können entweder statisch zufällig, nicht auflösbar privat oder auflösbar privat sein und diese Typen werden durch ein Bitmuster in den beiden höchstwertigen Bytes (11, 00 bzw. 10) getrennt.

Aber ich sehe nirgendwo, dass Sie öffentliche und zufällige Adressen trennen können, indem Sie nur die 48 Bits in der Adresse betrachten.

Wie funktioniert das in der Android-API? Woher wissen sie, mit welchem ​​Gerät sie sich verbinden sollen, wenn sie nicht wissen, ob die von Ihnen angegebene Adresse öffentlich oder zufällig ist?

Bei der betreffenden API handelt es sich beispielsweise um die Funktion getRemoteDevice . Es sagt:

Valid Bluetooth hardware addresses must be upper case, in a format such as
"00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available
to validate a Bluetooth address.

A BluetoothDevice will always be returned for a valid hardware address,
even if this adapter has never seen that device.

Sie geben der Funktion also 48 Datenbits und können nicht feststellen, ob die Adresse öffentlich oder privat ist. Dies bedeutet, dass das Gerät nicht eindeutig identifiziert ist.

22

Da offenbar niemand eine Antwort zu haben scheint, habe ich selbst mit dem Testen begonnen.

Ich habe versucht, eine App zu erstellen, die ein Gerät aus einer Zeichenfolgendarstellung einer Adresse erstellt, und versuchte, das Gerät mit der 48-Bit-Adresse einzurichten, indem das öffentliche oder private Bit abwechselnd angezeigt wird, um zu sehen, was der Android-Stack tut.

private final BluetoothGattCallback leGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i("Fisken", "Gatt connected " + gatt.getDevice().getAddress() + " status " + status);
            if (status != BluetoothGatt.GATT_SUCCESS) {
                Log.w("Fisken", "Disconnect and close");
                gatt.disconnect();
                gatt.close();
            }
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i("Fisken", "Gatt disconnected " + gatt.getDevice().getAddress() + " status " + status);
            if (status != BluetoothGatt.GATT_SUCCESS) {
                Log.w("Fisken", "Disconnect and close");
                gatt.disconnect();
            }
            gatt.close();
        }
    }
};

BluetoothAdapter mBluetoothAdapter = ((BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
BluetoothDevice d = mBluetoothAdapter.getRemoteDevice("FF:55:44:33:22:11");
d.connectGatt(this, false, leGattCallback);

Wenn ich mit diesem Code mein BLE-Peripheriegerät mit einer zufälligen Adresse starte, funktioniert alles wie erwartet. Wenn ich jedoch versuche, dieselbe Adresse mit dem öffentlichen Bit zu verwenden, sagt logcat "Gatt connected", aber das stimmt einfach nicht. Und ich kann mich nie trennen.

Update : Ich habe noch ein paar Tests gemacht, um das herauszufinden. Das onConnectionStateChange-Ereignis, das ich bekomme, ist nur der Verbindungsversuch, der ausfällt. Der Status ist entweder auf 133 (wenn ich STATE_CONNECTED erhalte) oder 257 (wenn ich eine STATE_DISCONNECTED bekomme) gesetzt und ich habe beide gesehen. In beiden Fällen sollte ich den Verbindungsversuch abbrechen (und jetzt im Beispielcode ausführen) und den Client schließen.

Ich habe auch herausgefunden, dass, wenn ich zuerst einen Scan durchführe, das Gerät, mit dem ich mich verbinden möchte, kürzlich gesehen wurde und dann eine Verbindung ausschließlich über die MAC-Adresse des Geräts herstellt, dann bin ich dazu in der Lage Verbinden Sie sich problemlos mit beliebigen Adressen und öffentlichen Adressen.

Dies scheint also ein Fehler zu sein und/oder eine fehlende Funktion in der Android-API. Es ist nicht möglich, eine Verbindung zu einer öffentlichen Adresse herzustellen, ohne zuvor nach einer Adresse gesucht zu haben. Es funktioniert jedoch für zufällige Adressen.

9

Es ist möglich zu erraten, ob die Adresse öffentlich oder zufällig ist, obwohl sie nicht in jedem Fall funktioniert.

Wie Sie oben sagen, sind bei einer zufälligen Adresse beide MSB entweder 00xx, 01xx oder 11xx ... Wenn es sich also um 10xx handelt, handelt es sich um eine öffentliche Adresse (von einer Firma, deren OUI mit 8,9, A oder beginnt B)

Außerdem ist die Anzahl der registrierten OUI im Vergleich zu den vorhandenen sehr begrenzt. Durch das Durchsuchen der potenziellen OUI in der IEEE-Datenbank wird ein übereinstimmendes Ergebnis wahrscheinlich eine öffentliche Adresse bedeuten.

Registrierte OUI-Anzahl: ~ 20500, also 0,12% von 2 ^ 24 Bits und 0,48% von 2 ^ 22 Bits.

Ohne die IEEE-Datenbank kann man sich darauf verlassen, dass das erste LSB einer OUI immer 0 ist und das zweite LSB fast immer 0 ist (eigentlich sollte es immer 0 sein, da diese Adressen universell verwaltet werden).

Es kann auch eine andere statistische Analyse verwendet werden: Zum Beispiel beginnen 60% der OUI mit 00. Andererseits hat eine nicht auflösbare private Adresse nur eine Wahrscheinlichkeit von 1,66%, um mit 00 zu beginnen (mit einem einheitlichen Zufallsgenerator).

1
calandoa

Ich denke, dass Ihr Original "49 Bits benötigt, um zwischen öffentlichen und zufälligen Adressen zu unterscheiden", richtig ist. Ich kann in der Kodierung einer öffentlichen IEEE-Adresse nichts finden, was die MSB auf "10" beschränkt, was, falls zutreffend, das Problem lösen würde.

Das Einzige, was man verwenden kann, ist die Bit-Einstellung "Random Address" in den Anzeigen des Peripheriegeräts oder die entsprechende Bit-Einstellung im Verbindungsinitiierungspaket der Zentrale. Wenn diese Bits nicht gesetzt sind, ist die Adresse, die der Endpunkt verfügbar macht, öffentlich.

Ich füge hinzu: Von der Kernspezifikation Band 6, Teil B, Abschnitt 1.3 Geräteadressen: Aufruf von MS = höchstwertig

Static random address:          two MB bits of MS byte are 1 1 such that the MS byte is 11xxxxxx & with 0xC0
Non-resolvable private address: two MB bits of MS byte are 0 0 such that the MS byte is 00xxxxxx & with 0x00
Resolvable private address:     two MB bits of MS byte are 0 1 such that the MS byte is 01xxxxxx & with 0x40

Es gibt keine Möglichkeit, eine öffentliche Adresse von einem der oben genannten Adresstypen zu unterscheiden, ohne auch das Adresstypflag zu haben. Also die Notwendigkeit für das '49.' Bit (das Zusatzflag). Die Adresse alleine macht es nicht!

0
Brian Reinhold

Ob die Werbeadresse öffentlich oder privat ist, wird im Header der Werbebotschaft festgelegt. Wenn Sie den Adresstyp in der Anwendungsebene auf "public" setzen, wird die tatsächliche "MAC" -Adresse von der BLE-Verbindungsschicht übertragen. Wenn Sie den Adresstyp auf statisch/privat auflösbar setzen, bedeutet dies, dass die BLE-Verbindungsschicht die Adresse mit einem Identitätsauflösungsschlüssel (IRK) verschlüsselt.

0
Freddy

Sie können zwischen öffentlichen und privaten Adressen unterscheiden, indem Sie die 2 höchstwertigen Bits betrachten. Eine Adresse ist 48 Bit lang und nicht 49 Bit. Siehe Core Bluetooth-Spezifikation v4.2, Band 6, Teil B, Abschnitt 1.3.

0
speedycat