Key Management
Keys live in two sets: current (what’s on the tag now) and target (what you
want after changeKeys()). A key config is { masterKey, diversify, systemIdentifier?, applicationId?, keyVersion? }
— keyVersion applies to target keys. When diversify is true, the effective key
is derived per-tag from the master key + UID (AN10922); setSystemIdentifier /
setApplicationId set the global diversification inputs.
Typical key-change flow: load the current keys (so the tag can authenticate), set
the target keys, then changeKeys().
Loading Key Sets
loadKeyConfig(config)
Load a complete configuration in one call. config.currentKeys is { keyNo: { masterKey, diversify, ... } }, config.targetKeys is { keyNo: { masterKey, diversify, keyVersion, ... } }, and config.systemIdentifier / config.applicationId are optional global inputs.
const res = tag.loadKeyConfig({ currentKeys: { 0: { masterKey: '00000000000000000000000000000000' } }, targetKeys: { 0: { masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42' } },});Returns
{ success: true, data: { configuration: { currentKeys: { 0: { masterKey: '00000000000000000000000000000000' } }, targetKeys: { 0: { masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42' } }, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' } }}loadFactoryDefaults()
Reset the KeyManager to factory defaults (all keys 00…00). Affects the in-memory key config only, not the tag.
const res = tag.loadFactoryDefaults();Returns
{ success: true, data: { message: 'Factory defaults loaded' }}Setting Individual Keys
setCurrentKey(keyNo, config)
Set a single current key (what the tag holds, used to authenticate). keyNo is 0–4; config is { masterKey, diversify, ... }.
const res = tag.setCurrentKey(0, { masterKey: '00000000000000000000000000000000' });Returns
{ success: true, data: { keyType: 'current', keyNo: 0, configuration: { masterKey: '00000000000000000000000000000000', systemIdentifier: 'CRYPTAG', applicationId: '3042F5' } }}setTargetKey(keyNo, config)
Set a single target key (the desired key after changeKeys()). keyNo is 0–4; config is { masterKey, diversify, keyVersion, ... }.
const res = tag.setTargetKey(1, { masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversify: true });Returns
{ success: true, data: { keyType: 'target', keyNo: 1, configuration: { masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversify: true, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' } }}getCurrentKey(keyNo)
The current key in hex (diversified if configured and a UID is cached). Returns the 32-hex string, or null if unset.
tag.getCurrentKey(0);// → '00000000000000000000000000000000'getTargetKey(keyNo)
The target key in hex (diversified if configured and a UID is cached). Returns the 32-hex string, or null if unset.
tag.getTargetKey(1);// → 'D3F7A91C5E08B264A1F9C7E03B5D8A42'getCurrentKeys()
The full current keys object (all 5 slots).
tag.getCurrentKeys();Returns
{ 0: { type: 'current', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' }, 1: { type: 'current', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' }, 2: { type: 'current', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' }, 3: { type: 'current', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' }, 4: { type: 'current', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5' }}getTargetKeys()
The full target keys object (all 5 slots).
tag.getTargetKeys();Returns
{ 0: { type: 'target', masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5', keyVersion: 1 }, 1: { type: 'target', masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversify: true, systemIdentifier: 'CRYPTAG', applicationId: '3042F5', keyVersion: 1 }, 2: { type: 'target', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5', keyVersion: 0 }, 3: { type: 'target', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5', keyVersion: 0 }, 4: { type: 'target', masterKey: '00000000000000000000000000000000', diversify: false, systemIdentifier: 'CRYPTAG', applicationId: '3042F5', keyVersion: 0 }}Changing Keys on the Tag
getKeyChangePlan(uid?)
Compare current vs target and report what will change before you run changeKeys(). uid (default null) is a 14-hex UID for diversified keys (defaults to the cached tag UID).
const res = await tag.getKeyChangePlan('04A1B2C3D4E580');Returns
{ success: true, data: { plan: [ { keyNo: 0, current: '00000000000000000000000000000000', target: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversified: false, newKeyVersion: 1, willChange: true }, { keyNo: 1, current: '00000000000000000000000000000000', target: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', diversified: true, newKeyVersion: 1, willChange: true }, { keyNo: 2, current: '00000000000000000000000000000000', target: '00000000000000000000000000000000', diversified: false, newKeyVersion: 0, willChange: false }, { keyNo: 3, current: '00000000000000000000000000000000', target: '00000000000000000000000000000000', diversified: false, newKeyVersion: 0, willChange: false }, { keyNo: 4, current: '00000000000000000000000000000000', target: '00000000000000000000000000000000', diversified: false, newKeyVersion: 0, willChange: false } ] }, duration: 11}changeKeys()
Change all keys on the tag to match the target configuration. Changes keys 1–4 first, then Key 0 (auth: Key 0, automatic).
tag.setTargetKey(0, { masterKey: 'D3F7A91C5E08B264A1F9C7E03B5D8A42' });const res = await tag.changeKeys();if (res.data.allSuccess) console.log('all keys changed');Returns
{ success: true, data: { changed: [ { keyNo: 1, success: true, version: 1, error: null }, { keyNo: 2, success: true, version: 0, error: null }, { keyNo: 3, success: true, version: 0, error: null }, { keyNo: 4, success: true, version: 0, error: null }, { keyNo: 0, success: true, version: 1, error: null } ], totalChanged: 5, allSuccess: true }, duration: 38}Diversification Inputs
setSystemIdentifier(systemIdentifier)
Set the global system ID (ASCII, max 8 chars).
const res = tag.setSystemIdentifier('CRYPTAG');Returns
{ success: true, data: { systemIdentifier: 'CRYPTAG' }}getSystemIdentifier()
Read the global system ID back.
tag.getSystemIdentifier();// → 'CRYPTAG'setApplicationId(applicationId)
Set the global application ID (6 hex chars / 3 bytes).
const res = tag.setApplicationId('3042F5');Returns
{ success: true, data: { applicationId: '3042F5' }}getApplicationId()
Read the global application ID back.
tag.getApplicationId();// → '3042F5'Generating Keys
generateRandomKey()
A cryptographically secure random 128-bit AES key (32-hex, uppercase).
tag.generateRandomKey();// → 'D3F7A91C5E08B264A1F9C7E03B5D8A42'generateRandomKeySet()
Five random keys, one per slot.
tag.generateRandomKeySet();Returns
{ 0: 'D3F7A91C5E08B264A1F9C7E03B5D8A42', 1: '7B2E9F40A1C8D356E0F94B7A2C5D8E13', 2: 'A1F9C7E03B5D8A42D3F7A91C5E08B264', 3: 'C5D8E1377B2E9F40A1C8D356E0F94B7A', 4: 'E0F94B7AA1C8D3567B2E9F40C5D8E137'}Saving & Loading Keysets
setKeysetsFolder(folderPath)
Base folder for exportKeyConfig / importKeyConfig. Pass an absolute path to decouple keyset files from the process CWD — recommended for desktop apps (e.g. an Electron userData directory).
import { app } from 'electron';const res = tag.setKeysetsFolder(`${app.getPath('userData')}/keysets`);Returns
{ success: true, data: { keysetsFolder: '/home/user/.config/cryptag/keysets' }}exportKeyConfig(fileName)
Write the full key configuration to <folder>/<fileName>.keyset.json. fileName is a bare name — no path separators or ...
const res = await tag.exportKeyConfig('site-a'); // -> <folder>/site-a.keyset.jsonReturns
{ success: true, data: { message: 'Key configuration exported successfully', filePath: '/home/user/.config/cryptag/keysets/site-a.keyset.json', fileName: 'site-a.keyset.json', location: '/home/user/.config/cryptag/keysets', fileSize: 842 }, duration: 9}importKeyConfig(fileName)
Read the full key configuration from <folder>/<fileName>.keyset.json. Resets to factory first (replace, not merge) and fully rolls back on any error.
const res = await tag.importKeyConfig('site-a');Returns
{ success: true, data: { message: 'Key configuration imported successfully', filePath: '/home/user/.config/cryptag/keysets/site-a.keyset.json', fileName: 'site-a.keyset.json', location: '/home/user/.config/cryptag/keysets', metaData: { exportDate: '2026-06-01T10:15:42.000Z', exportTimestamp: 1780042542000, version: '1.0', description: 'CrypTag keyset export' }, status: { currentIsFactoryDefault: true, targetIsFactoryDefault: false, needsKeyChange: true, hasTagUID: false } }, duration: 12}