Search code examples
androidreact-nativenfcreact-native-nfc-manager

React Native (not Expo): Set and Verify Password on NTAG216 with `react-native-nfc-manager`


I'm building a React Native app (not using Expo) that interacts with NXP NTAG216 NFC tags. I'm successfully using react-native-nfc-manager to read and write data, but I'm struggling to implement password protection for write operations

Key Challenges:

  • I can't find a straightforward way to set and verify passwords using this library.

Specific Questions:

  1. Is it possible to directly set and verify password protection on NTAG216 tags with react-native-nfc-manager? If so, what specific methods or approach does the library offer?
  2. If react-native-nfc-manager doesn't support password protection, are there alternative libraries or strategies I can explore? I'm open to using custom commands or lower-level communication if necessary.

Code Snippets:

import React from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import NfcManager, {Ndef, NfcTech, nfcManager} from 'react-native-nfc-manager';

// Pre-step, call this before any NFC operations
NfcManager.start();

function App() {
  async function readNdef() {
    try {
      console.log('🚀 ~ readNdef ~ NfcManager:', 'entered');
      // register for the NFC tag with NDEF in it
      await NfcManager.requestTechnology(NfcTech.Ndef);
      // the resolved tag object will contain `ndefMessage` property
      const tag = await NfcManager.getTag();
      console.warn('Tag found', tag);
    } catch (ex) {
      console.warn('Oops!', ex);
    } finally {
      // stop the nfc scanning
      console.log('exited');
      NfcManager.cancelTechnologyRequest();
    }
  }
  function buildUrlPayload(valueToWrite) {
    return Ndef.encodeMessage([Ndef.uriRecord(valueToWrite)]);
  }
  const writeNFC = async () => {
    let result = false;

    try {
      await NfcManager.requestTechnology(NfcTech.Ndef);
      const bytes = buildUrlPayload(
        'https://stackoverflow.com/questions/11896981/change-nfc-tag-to-be-read-only',
      );
      await NfcManager.ndefHandler.writeNdefMessage(bytes);
      console.log('🚀 ~ writeNFC ~ bytes:', bytes);
      console.log('makeReadOnly');
    } catch (ex) {
      console.warn(ex);
    } finally {
      console.log('eixt write');
      NfcManager.cancelTechnologyRequest();
    }

    return result;
  };
  return (
    <View style={styles.wrapper}>
      <TouchableOpacity onPress={readNdef}>
        <Text>Scan a Tag</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={writeNFC}>
        <Text style={{color: 'grey'}}>Write Tag</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App;

Version Information:

  • Node.js version: v18.17.1
  • React version: 18.2.0
  • React Native version: 0.73.4
  • react-native-nfc-manager version: 3.14.12

NFC Tag Infomation:

enter image description here

Desired Outcome: Understand how to implement password protection on NTAG216 tags in my React Native app, either with react-native-nfc-manager or an alternative approach.


Solution

  • Some answers

    Q1) Yes it is possible set and verify a password with react-native-nfc-manager

    Q2) Password setting is not part of the NFC standards, various Tag hardware families each tend to have a different way of implementing password protection, so you have to interact with the Tag's at a lower level than the Ndef Data format. It's unlikely for other libraries to support it direct other than at a lower level that react-native-nfc-manager can also use.

    So some background reading first, you should read and understand the Ntag21x's datasheet, specifically Section 8.8 and 10.7

    Your code need to access the Tag at the NfcA level.

    so code something like

    await NfcManager.requestTechnology(NfcTech.NfcA);
    // Build a byte array to send to Tag
    const commandBytes = [162,...,...]
    const responceBytes = await NfcManager.NfcAHandler.transceive(commandBytes)
    // Check response
    // Repeat until all the necessary commands are sent
    

    The general set of command to set a password are defined in the datasheet and are platform independent and the are a number of stackoverflow question about password setting like https://stackoverflow.com/a/63259021/2373819