title: Bluetooth Secure Simple Pairing (SSP) using QR code as Out of Band (OOB) channel
body: <p>I have a Windows 7 application, which uses <a href="http://www.stollmann.de/en/software/nfc/nfc-for-windows.html" rel="noreferrer">Stollmann SDK</a> to successfully bond PC with Android. The <em>bidirectional</em> exchange of Bluetooth MAC address, hash and randomizer is carried out <em>out of band</em> via NFC:</p>
  
  <p><img src="https://i.stack.imgur.com/ypdMr.png" alt="application with qr code"></p>
  
  <p>The source code of the Windows application unfortunately can not be shared here. On the Android side no app is needed and the <em>Secure Simple Pairing</em> is performed by the operating system (by <a href="https://github.com/android-ia/platform_packages_apps_Nfc/blob/master/src/com/android/nfc/handover/HandoverManager.java" rel="noreferrer">HandoverManager</a>?) once an NDEF message with <code>application/vnd.bluetooth.ep.oob</code> is received.</p>
  
  <p>Now I am trying to create <a href="https://github.com/afarber/android-newbie/tree/master/QR_BT_Pairing" rel="noreferrer">an Android app</a>, which would use <em>unidirectional</em> authentication to perform OOB pairing via scanned QR code (instead of NFC).</p>
  
  <p>A custom QR code would be shown at PC screen (generated by <a href="https://zxingnet.codeplex.com" rel="noreferrer">ZXing.Net</a>) and contain Bluetooth MAC address, hash and randomizer.</p>
  
  <p>However OOB bonding seems to be not implemented yet in Android -</p>
  
  <p><a href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/bluetooth/BluetoothAdapter.java" rel="noreferrer">BluetoothAdapter.java</a>:</p>
  
  <pre><code>/**
   * Read the local Out of Band Pairing Data
   * &lt;p&gt;Requires {@link android.Manifest.permission#BLUETOOTH}
   *
   * @return Pair&lt;byte[], byte[]&gt; of Hash and Randomizer
   *
   * @hide
   */
  public Pair&lt;byte[], byte[]&gt; readOutOfBandData() {
      if (getState() != STATE_ON) return null;
      //TODO(BT
      /*
      try {
          byte[] hash;
          byte[] randomizer;
  
          byte[] ret = mService.readOutOfBandData();
  
          if (ret  == null || ret.length != 32) return null;
  
          hash = Arrays.copyOfRange(ret, 0, 16);
          randomizer = Arrays.copyOfRange(ret, 16, 32);
  
          if (DBG) {
              Log.d(TAG, "readOutOfBandData:" + Arrays.toString(hash) +
                ":" + Arrays.toString(randomizer));
          }
          return new Pair&lt;byte[], byte[]&gt;(hash, randomizer);
  
      } catch (RemoteException e) {Log.e(TAG, "", e);}*/
      return null;
  }
  </code></pre>
  
  <p><a href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/bluetooth/BluetoothDevice.java" rel="noreferrer">BluetoothDevice.java</a>:</p>
  
  <pre><code>/**
   * Start the bonding (pairing) process with the remote device using the
   * Out Of Band mechanism.
   *
   * &lt;p&gt;This is an asynchronous call, it will return immediately. Register
   * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
   * the bonding process completes, and its result.
   *
   * &lt;p&gt;Android system services will handle the necessary user interactions
   * to confirm and complete the bonding process.
   *
   * &lt;p&gt;Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
   *
   * @param hash - Simple Secure pairing hash
   * @param randomizer - The random key obtained using OOB
   * @return false on immediate error, true if bonding will begin
   *
   * @hide
   */
  public boolean createBondOutOfBand(byte[] hash, byte[] randomizer) {
      //TODO(BT)
      /*
      try {
          return sService.createBondOutOfBand(this, hash, randomizer);
      } catch (RemoteException e) {Log.e(TAG, "", e);}*/
      return false;
  }
  
  /**
   * Set the Out Of Band data for a remote device to be used later
   * in the pairing mechanism. Users can obtain this data through other
   * trusted channels
   *
   * &lt;p&gt;Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
   *
   * @param hash Simple Secure pairing hash
   * @param randomizer The random key obtained using OOB
   * @return false on error; true otherwise
   *
   * @hide
   */
  public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
    //TODO(BT)
    /*
    try {
      return sService.setDeviceOutOfBandData(this, hash, randomizer);
    } catch (RemoteException e) {Log.e(TAG, "", e);} */
    return false;
  }
  </code></pre>
  
  <p><strong>My question:</strong> </p>
  
  <p>Since OOB Bluetooth pairing works well over NFC on Android - do you think there is a (hackish) way to do the same via QR code?</p>
  
  <p>Maybe (crazy idea) by feeding <code>HandoverManager</code> with a fake NDEF message?</p>