Comments (6)
Everything works as expected. With this I was actually able to break it down even further.
I would like to detect which kind of NTAG chip I am using, as they all come with different pages for storing passwords and configs.
Here is something quick and dirty that helps identify the NTAG chip. Next step would be to return the appropriate offsets in an object property, such as model.offset = 123
async getModel(reader) {
try {
let cmd = Buffer.from([
0xFF, // Class
0x00, // Direct Transmit (see ACR122U)
0x00, // ...
0x00, // ...
0x03, // Length of Direct Transmit payload
0xd4, // Data Exchange Command (see PN533 docs)
0x42, // inserted
0x60, // GET_VERSION
]);
let response = await reader.transmit(cmd, 13);
// console.log('+--- Vendor :', response[4]);
// console.log('+--- Type :', response[5]);
// console.log('+--- SubType :', response[6]);
// console.log('+--- Version 0 :', response[7]);
// console.log('+--- Version 1 :', response[8]);
// console.log('+--- Storage :', response[9]);
let model = {};
model.name = null;
model.page = null;
if(response[4] === 4 && response[5] === 4) {
if(response[6] === 1 && response[7] === 1 && response[8] === 0 && response[9] === 11) {
model.name = "NTAG210";
} else if(response[6] === 1 && response[7] === 1 && response[8] === 0 && response[9] === 14) {
model.name = "NTAG212";
} else if(response[6] === 2 && response[7] === 1 && response[8] === 0 && response[9] === 15) {
model.name = "NTAG213";
} else if(response[6] === 4 && response[7] === 1 && response[8] === 0 && response[9] === 15) {
model.name = "NTAG213F";
} else if(response[6] === 2 && response[7] === 1 && response[8] === 0 && response[9] === 17) {
model.name = "NTAG215";
} else if(response[6] === 2 && response[7] === 1 && response[8] === 0 && response[9] === 19) {
model.name = "NTAG216";
} else if(response[6] === 4 && response[7] === 1 && response[8] === 0 && response[9] === 19) {
model.name = "NTAG216F";
}
}
return model;
} catch (err) {
console.error('get_version error', err);
}
Reference guide for this:
// get version
> FF 00 00 00 03 D4 42 60
// response
< D5 43 00 00 04 04 02 01 00 13 03 90 00
Details:
Vendor (04 = NXP)
|
D5 43 00 00 04 04 02 01 00 13 03 90 00
| | | | |
+------------+------+---------+-----------+--------------+
| Chip | Type | Subtype | Version | Storage size |
+------------+------+---------+-----------+--------------+
| NTAG210 | 0x04 | 0x01 | 0x01 0x00 | 0x0B |
| NTAG212 | 0x04 | 0x01 | 0x01 0x00 | 0x0E |
| NTAG213 | 0x04 | 0x02 | 0x01 0x00 | 0x0F |
| NTAG213F | 0x04 | 0x04 | 0x01 0x00 | 0x0F |
| NTAG215 | 0x04 | 0x02 | 0x01 0x00 | 0x11 |
| NTAG216 | 0x04 | 0x02 | 0x01 0x00 | 0x13 |
| NTAG216F | 0x04 | 0x04 | 0x01 0x00 | 0x13 |
+------------+------+---------+-----------+--------------+
| NT3H1101 | 0x04 | 0x02 | 0x01 0x01 | 0x13 |
| NT3H1101W0 | 0x04 | 0x05 | 0x02 0x01 | 0x13 |
| NT3H2111W0 | 0x04 | 0x05 | 0x02 0x02 | 0x13 |
| NT3H2101 | 0x04 | 0x02 | 0x01 0x01 | 0x15 |
| NT3H1201W0 | 0x04 | 0x05 | 0x02 0x01 | 0x15 |
| NT3H2211W0 | 0x04 | 0x05 | 0x02 0x02 | 0x15 |
+------------+------+---------+-----------+--------------+
| MF0UL1101 | 0x03 | 0x01 | 0x01 0x00 | 0x0B |
| MF0ULH1101 | 0x03 | 0x02 | 0x01 0x00 | 0x0B |
| MF0UL2101 | 0x03 | 0x01 | 0x01 0x00 | 0x0E |
| MF0ULH2101 | 0x03 | 0x02 | 0x01 0x00 | 0x0E |
+------------+------+---------+-----------+--------------+
==> NTAG Technical Doc, Table 28
And yes, NFC technical guides are tough to dig through. So good code examples would help beginners to kick off faster.
Cheers :-)
from nfc-pcsc.
Hi @bierlair,
thank you for posting your issue here.
According to the official documentation, it is possible to protect NTAG21x cards with password.
To read/write (based on your card's access config) password protected cards, you need to authenticate using PWD_AUTH command first.
And all these things should be doable using ACR122U and nfc-pcsc library. 😃
I don't know, where the problem might be. Could you please answer the following questions so that we can find why it doesn't work?
-
What operating system, what reader, and card (I suppose NTAG21x) do you use?
-
Are you able to read unprotected NTAG21x card?
-
What's the content of
pwdResponse
? Can you log it and send it here?
pwdResponse
response should look like the following (7 bytes):d5 43 00 XX XX 90 00 byte 0: d5 prefix for response of Data Exchange Command (see PN533 docs) byte 1: 43 prefix for response of Data Exchange Command (see PN533 docs) byte 2: Data Exchange Command Status 0x00 is success (see PN533 docs) bytes 3-4: Data Exchange Command Response – PACK (2 bytes password acknowledgment) from card bytes 5-6: ACR122U success code
Note about
PACK
: You can change the value. It is stored in the last configuration page of the card, see the docs (8.5 Memory organization) -
Just for sure: Make sure you authenticate and read data from card in the same session. You have to authenticate the card every time you attach it.
Hope it helps. 🙂
Looking forward to your reply. I believe we make it work together. 🙂
To be honest, I have never tried to access protected cards before. I don't have any experience with NTAG21x cards (only with Mifare Ultralight EV1, Classic, and DESFire EV1).
Fortunately, according to the documentation, I have been able to make it work on Mifare Ultralight EV1 (it is very similar to NTAG21x cards, it even uses same commands). After I issue PWD_AUTH command, I am able to read the (password-read-protected) memory. 🚀
Here is my code to authenticate card:
reader.on('card', async card => {
console.log('card detected', card);
// PASSWORD (4 bytes) (stored on card in page 18)
const password = Buffer.from([
0xff,
0xff,
0xff,
0xff,
]);
// PACK (2 bytes) (stored in page 19 as first two bytes)
// PACK is the response from card in case of successful PWD_AUTH cmd
const pack = Buffer.from([
0xab,
0xcd
]);
try {
// CMD: PWD_AUTH via Direct Transmit (ACR122U) and Data Exchange (PN533)
const cmd = Buffer.from([
0xFF, // Class
0x00, // Direct Transmit (see ACR122U)
0x00, // ...
0x00, // ...
0x07, // Length of Direct Transmit payload
// Payload (7 bytes)
0xd4, // Data Exchange Command (see PN533 docs)
0x42, // inserted
0x1b, // PWD_AUTH
...password,
]);
console.log('pwd_auth cmd', cmd);
const response = await reader.transmit(cmd, 7);
console.log('pwd_auth response', response);
// pwd_auth response should look like the following (7 bytes)
// d5 43 00 ab cd 90 00
// byte 0: d5 prefix for response of Data Exchange Command (see PN533 docs)
// byte 1: 43 prefix for response of Data Exchange Command (see PN533 docs)
// byte 2: Data Exchange Command Status 0x00 is success (see PN533 docs)
// bytes 3-4: Data Exchange Command Response – our PACK (set on card in page 19, in bytes 0-1) from card
// bytes 5-6: ACR122U success code
} catch (err) {
console.error('pwd_auth error', err);
return;
}
});
That's how I set up the password protection (don't allow to read content without authentication):
reader.on('card', async card => {
try {
// set custom PASSWORD (4 bytes) (stored in page 18)
await reader.write(19, password);
// set custom PACK (2 bytes) (stored in page 19 as first two bytes)
const packPage = await reader.read(19, 4);
packPage[0] = pack[0];
packPage[1] = pack[1];
await reader.write(19, packPage);
// read current configuration
const config = await reader.read(16, 8);
// Configuration page 16
console.log(config[0]);
console.log(config[1]);
console.log(config[2]);
console.log(config[3]); // AUTH0 (default: 0xff)
// Configuration page 17
console.log(config[4]); // ACCESS
console.log(config[5]); // VCTID (default: 0x05)
console.log(config[6]);
console.log(config[7]);
// Protect everything (start with first data page)
config[3] = 0x04;
// set ACCESS bits
// bit 7: PROT One bit inside the ACCESS byte defining the memory protection
// 0b ... write access is protected by the password verification
// 1b ... read and write access is protected by the password verification
// bit 6: CFGLCK Write locking bit for the user configuration
// - 0b ... user configuration open to write access
// - 1b ... user configuration permanently locked against write access
// bits 5-3: reserved
// bits 2-0: AUTHLIM
// bit number-76543210
// ||||||||
config[4] = 0b10000000;
// set custom access rules
await reader.write(16, config);
} catch (err) {
console.error(err);
}
});
from nfc-pcsc.
Awesome, this is exactly what I needed.
I was pretty close to completing this myself by reading the technical docs of NTAG21x, but your code snippet accelerated things.
Since I am working with NTAG216, I needed to adjust the page addresses.
The try/catch block for setting the password now looks something like this:
try {
// set custom PASSWORD (4 bytes) (stored in page 229)
await reader.write(229, password);
// set custom PACK (2 bytes) (stored in page 230 as first two bytes)
const packPage = await reader.read(230, 4);
packPage[0] = pack[0];
packPage[1] = pack[1];
await reader.write(230, packPage);
// read current configuration
const config = await reader.read(227, 8);
// Configuration page 16
console.log(config[0]);
console.log(config[1]);
console.log(config[2]);
console.log(config[3]); // AUTH0 (default: 0xff)
// Configuration page 17
console.log(config[4]); // ACCESS
console.log(config[5]); // VCTID (default: 0x05)
console.log(config[6]);
console.log(config[7]);
// Protect everything (start with first data page)
config[3] = 0x04;
// set ACCESS bits
// bit 7: PROT One bit inside the ACCESS byte defining the memory protection
// 0b ... write access is protected by the password verification
// 1b ... read and write access is protected by the password verification
// bit 6: CFGLCK Write locking bit for the user configuration
// - 0b ... user configuration open to write access
// - 1b ... user configuration permanently locked against write access
// bits 5-3: reserved
// bits 2-0: AUTHLIM
// bit number-76543210
// ||||||||
config[4] = 0b10000000;
// set custom access rules
await reader.write(227, config);
} catch (err) {
console.error(err);
}
Thanks again 👍
from nfc-pcsc.
@bierlair That's great. 👍
So everything works as expected? Can we close the issue?
BTW I think, it would be useful to have this in the examples. Thank you very much for pointing it out to me. In future, the examples should explain the basic usage and commands of the most popular cards and tags to help people to get started easily. From my experience, I can say, that regarding NFC standards and cards, there is a lack of documentation (or it is poor, hard to find and understand, especially for beginners).
PS Don't forget to star ⭐️ my library, if you find it useful. 😃 Thanks.
from nfc-pcsc.
@pokusew Hello, I am currently using ACS ACR 1252 1S CL Reader PICC 0 for my Mifare Ultralight. I wish to add a password to my tag so that others can write on it if they enter the password. Could I know what platform are you guys using to code and link with the reader because I am unable to find it. Thank you!
from nfc-pcsc.
Hello, I want to add a password protection after writing data on NTAG216. I tried @bierlair code sample but the last writing command break my nfc cards...
This in my code:
// PASSWORD (4 bytes) (stored on card in page 18)
const CARD_PASSWORD = Buffer.from([
0xff,
0xff,
0xff,
0xff,
]);
// PACK (2 bytes) (stored in page 19 as first two bytes)
// PACK is the response from card in case of successful PWD_AUTH cmd
const PACK = Buffer.from([
0xab,
0xcd
]);
// set custom PASSWORD (4 bytes) (stored in page 229)
await reader.write(229, CARD_PASSWORD);
// set custom PACK (2 bytes) (stored in page 230 as first two bytes)
const packPage = await reader.read(230, 4);
packPage[0] = PACK[0];
packPage[1] = PACK[1];
await reader.write(230, packPage);
const config = await reader.read(227, 8);
config[3] = 0x04;
config[4] = 0b10000000;
await reader.write(227, config);
Could you please help me to find a solution ? Thanks all
from nfc-pcsc.
Related Issues (20)
- Constructing APDU command on NTAG21x
- Error when writing data. Receives an Invalid data length error. HOT 3
- Authentication failed for same blocks BUT is Working in others HOT 1
- P2P Feature
- Empty Data
- Multi RFID Reader
- was compiled against a different Node.js version using NODE_MODULE_VERSION 111. This version of Node.js requires NODE_MODULE_VERSION 110. HOT 3
- UnhandledPromiseRejectionWarning: WriteError: Write operation failed: Status code: 0x6300 HOT 3
- I don't understand that code HOT 1
- Module not found: Error: Can't resolve 'fs' HOT 2
- Unable to run the basic example HOT 2
- Add disposition parameter in disconnect method HOT 2
- MacOS installation issue using npm HOT 2
- Cannot access "events.EventEmitter" in client code HOT 4
- Context Aware Native Module, Electron Context Isolation and Node Integration Support
- Unsupported engine Please Help
- Emulate Tag NFC?
- Sveltekit build fails when running 'npm run build' but works on 'npm run dev' HOT 1
- It turned out to connect the library in CRA(React)? HOT 1
- Writes become slower each time
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nfc-pcsc.