NFC Encoding Guide
Properly encoding NFC chips ensures secure, tamper-proof product authentication.
Prerequisites
Before you begin encoding NFC chips, ensure you have the following:
- NFC Writer Device - A compatible NFC reader/writer (ACR122U, SCL3711, or similar)
- TAG IT Approved Chips - NTAG 424 DNA or similar secure NFC chips
- TAG IT Encoding Software - Download from your dashboard or use the SDK
- API Access - Valid API credentials with encoding permissions
- Secure Environment - Encoding should be performed in a controlled environment
For production encoding, we recommend using our certified encoding stations. Contact sales for enterprise solutions.
Encoding Flow
The TAG IT encoding process follows these steps to ensure secure chip initialization:
- Initialize Session - Authenticate with the TAG IT API and create an encoding session
- Read Chip UID - Capture the unique identifier from the blank NFC chip
- Generate Keys - Request cryptographic keys from the TAG IT key management system
- Write NDEF Records - Program the authentication URL and metadata
- Configure Security - Set up counters, signatures, and access controls
- Lock Configuration - Permanently lock security settings to prevent tampering
- Register on Blockchain - Create the on-chain product record
- Verify Encoding - Perform a test scan to confirm successful encoding
// Complete encoding flow example
import { TagIt } from '@tagit/sdk';
const tagit = new TagIt({
apiKey: process.env.TAGIT_API_KEY,
network: 'mainnet'
});
async function encodeNFCChip(chipUID, productData) {
// Step 1: Create encoding session
const session = await tagit.encoding.createSession({
chipUID: chipUID,
productData: productData
});
// Step 2: Generate cryptographic keys
const keys = await tagit.encoding.generateKeys(session.id);
// Step 3: Prepare NDEF payload
const ndefPayload = await tagit.encoding.prepareNDEF({
sessionId: session.id,
authUrl: `https://verify.tagit.network/${session.tagId}`,
metadata: productData
});
// Step 4: Write to chip (requires NFC hardware)
const writeResult = await nfcWriter.write(ndefPayload);
// Step 5: Configure security features
await tagit.encoding.configureSecurity({
sessionId: session.id,
enableCounter: true,
enableSignature: true,
lockConfig: true
});
// Step 6: Register on blockchain
const registration = await tagit.encoding.register(session.id);
return {
tagId: session.tagId,
txHash: registration.txHash,
verifyUrl: ndefPayload.authUrl
};
}
Data Format
TAG IT uses NDEF (NFC Data Exchange Format) records to store authentication data on chips.
NDEF Record Structure
Each TAG IT chip contains the following NDEF records:
{
"records": [
{
"type": "U",
"id": "tagit-auth",
"payload": "https://verify.tagit.network/t/ABC123XYZ"
},
{
"type": "T",
"id": "tagit-meta",
"payload": {
"v": "1.0",
"sig": "base64_encoded_signature",
"cnt": "rolling_counter_value"
}
}
]
}
URL Structure
The authentication URL follows this format:
https://verify.tagit.network/t/{TAG_ID}?s={SIGNATURE}&c={COUNTER}
Parameters:
- TAG_ID: Unique 12-character alphanumeric identifier
- SIGNATURE: CMAC signature (16 bytes, hex encoded)
- COUNTER: Rolling counter value (3 bytes, hex encoded)
Security Features
TAG IT NFC chips incorporate multiple security layers to prevent counterfeiting and tampering.
Cryptographic Signatures
Each scan generates a unique CMAC (Cipher-based Message Authentication Code) signature using AES-128:
// Signature verification on server
async function verifySignature(tagId, signature, counter) {
const chip = await tagit.chips.get(tagId);
// Reconstruct the message that was signed
const message = Buffer.concat([
Buffer.from(chip.uid, 'hex'),
Buffer.from(counter, 'hex'),
Buffer.from(tagId)
]);
// Verify using the chip's secret key
const isValid = await tagit.crypto.verifyCMAC({
key: chip.authKey,
message: message,
signature: signature
});
return isValid;
}
Authentication keys are never exposed. All signature verification happens server-side through the TAG IT API.
Rolling Counters
A monotonically increasing counter prevents replay attacks:
- Counter increments with every tap/scan
- Server tracks expected counter range
- Out-of-sequence counters trigger fraud alerts
- Counter is included in signature calculation
// Counter validation logic
async function validateCounter(tagId, receivedCounter) {
const chip = await tagit.chips.get(tagId);
const counterValue = parseInt(receivedCounter, 16);
// Counter must be greater than last seen
if (counterValue <= chip.lastCounter) {
throw new Error('Replay attack detected: counter too low');
}
// Counter shouldn't jump too far (indicates cloning attempt)
if (counterValue > chip.lastCounter + 1000) {
await tagit.alerts.create({
type: 'COUNTER_ANOMALY',
tagId: tagId,
details: { expected: chip.lastCounter + 1, received: counterValue }
});
}
// Update stored counter
await tagit.chips.updateCounter(tagId, counterValue);
return true;
}
Tamper Detection
TAG IT chips can detect physical tampering attempts:
- Configuration Lock - Security settings cannot be modified after encoding
- Memory Protection - Critical data areas are write-protected
- UID Verification - Hardware UID cannot be cloned or modified
- Originality Check - Verify chip is genuine manufacturer hardware
Batch Encoding
For manufacturing environments, TAG IT supports high-volume batch encoding:
// Batch encoding for manufacturing
import { TagIt, BatchEncoder } from '@tagit/sdk';
const tagit = new TagIt({ apiKey: process.env.TAGIT_API_KEY });
async function batchEncode(products) {
// Create batch session
const batch = await tagit.encoding.createBatch({
name: 'Production Run 2024-001',
quantity: products.length,
productTemplate: {
brand: 'Premium Brand',
category: 'Luxury Goods'
}
});
const encoder = new BatchEncoder({
tagit: tagit,
batchId: batch.id,
onProgress: (progress) => {
console.log(`Encoded ${progress.completed}/${progress.total}`);
},
onError: (error, chip) => {
console.error(`Failed to encode ${chip.uid}: ${error.message}`);
}
});
// Process each chip
for (const product of products) {
await encoder.encodeNext({
serialNumber: product.serialNumber,
metadata: product.metadata
});
}
// Finalize batch and get report
const report = await encoder.finalize();
console.log(`Batch complete: ${report.successful}/${report.total} chips encoded`);
console.log(`Blockchain TX: ${report.registrationTxHash}`);
return report;
}
Batch encoding with parallel processing is available on Business and Enterprise plans. Contact sales for encoding station hardware.
Verifying Encoded Tags
After encoding, always verify that tags are properly programmed:
// Post-encoding verification
async function verifyEncodedTag(tagId) {
const verification = await tagit.encoding.verify(tagId);
const checks = {
ndefValid: verification.ndef.valid,
signatureValid: verification.security.signatureEnabled,
counterValid: verification.security.counterEnabled,
configLocked: verification.security.configurationLocked,
blockchainRegistered: verification.blockchain.registered,
urlAccessible: verification.connectivity.urlReachable
};
const allPassed = Object.values(checks).every(v => v === true);
if (!allPassed) {
console.error('Verification failed:', checks);
throw new Error('Tag encoding verification failed');
}
console.log('Tag verified successfully:', {
tagId: tagId,
verifyUrl: verification.urls.verify,
txHash: verification.blockchain.txHash
});
return verification;
}
Testing Checklist
- Scan tag with mobile device and verify redirect works
- Confirm product details display correctly on verification page
- Perform multiple scans and verify counter increments
- Check blockchain explorer for registration transaction
- Test with TAG IT mobile app for full verification flow
Troubleshooting
Common issues and their solutions:
Encoding Fails
- Check chip compatibility - Ensure using TAG IT approved NFC chips
- Verify writer connection - Confirm NFC writer is properly connected
- Check API credentials - Ensure API key has encoding permissions
- Retry with new chip - Some chips may be defective
Verification Fails After Encoding
- Wait for blockchain confirmation - Registration may take 1-2 minutes
- Check network connectivity - Ensure device has internet access
- Verify URL format - Check that NDEF URL is correctly formatted
Counter Anomalies
- Multiple rapid scans - Allow 1 second between scans
- Counter jump detected - May indicate attempted cloning, investigate
- Counter not incrementing - Check chip security configuration
For encoding support, contact our technical team at support@tagit.network or visit the Developer Forum.