fix(dukpt): add KSN/BDK to JSON output for AES and TDES DUKPT derive operations

AES DUKPT IK JSON was missing ksn, iki, counter; working key was missing ksn.
TDES DUKPT IPEK and session key JSON were missing ksn and bdk.
Both now mirror the full derivation context, making json=true self-contained for debugging and cross-validation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
J8k3 2026-05-23 10:23:41 -04:00
parent d7a32d1293
commit 4ce7860a19
3 changed files with 10 additions and 3 deletions

View File

@ -305,8 +305,9 @@ class DeriveDUKPTAESKey extends Operation {
if (deriveMode === "Initial Key (IK)") { if (deriveMode === "Initial Key (IK)") {
if (outputJson) { if (outputJson) {
const out = { inputKeyType, ik: hex(ik) }; const out = { inputKeyType, ksn: hex(ksn), iki: hex(iki), counter: `0x${counter.toString(16).padStart(8, "0").toUpperCase()}` };
if (inputKeyType === "BDK") out.bdk = hex(inputKey); if (inputKeyType === "BDK") out.bdk = hex(inputKey);
out.ik = hex(ik);
return JSON.stringify(out, null, 4); return JSON.stringify(out, null, 4);
} }
return hex(ik); return hex(ik);
@ -317,7 +318,7 @@ class DeriveDUKPTAESKey extends Operation {
const wkKey = deriveWorkingKey(txKey, iki, counter, purpose); const wkKey = deriveWorkingKey(txKey, iki, counter, purpose);
if (outputJson) { if (outputJson) {
const out = { inputKeyType, iki: hex(iki), counter: `0x${counter.toString(16).padStart(8, "0").toUpperCase()}` }; const out = { inputKeyType, ksn: hex(ksn), iki: hex(iki), counter: `0x${counter.toString(16).padStart(8, "0").toUpperCase()}` };
if (inputKeyType === "BDK") out.bdk = hex(inputKey); if (inputKeyType === "BDK") out.bdk = hex(inputKey);
out.ik = hex(ik); out.ik = hex(ik);
out.transactionKey = hex(txKey); out.transactionKey = hex(txKey);

View File

@ -253,9 +253,11 @@ class DeriveDUKPTKey extends Operation {
const ipek = deriveIpek(bdk, ksn); const ipek = deriveIpek(bdk, ksn);
const ipekHex = toHexFast(ipek).toUpperCase(); const ipekHex = toHexFast(ipek).toUpperCase();
const ksnHexOut = toHexFast(ksn).toUpperCase();
if (mode === "Derive IPEK") { if (mode === "Derive IPEK") {
if (outputJson) { if (outputJson) {
return JSON.stringify({ mode, ipek: ipekHex }, null, 4); return JSON.stringify({ mode, ksn: ksnHexOut, bdk: toHexFast(bdk).toUpperCase(), ipek: ipekHex }, null, 4);
} }
return ipekHex; return ipekHex;
} }
@ -267,6 +269,8 @@ class DeriveDUKPTKey extends Operation {
if (outputJson) { if (outputJson) {
return JSON.stringify({ return JSON.stringify({
mode, mode,
ksn: ksnHexOut,
bdk: toHexFast(bdk).toUpperCase(),
ipek: ipekHex, ipek: ipekHex,
sessionBase: toHexFast(sessionBase).toUpperCase(), sessionBase: toHexFast(sessionBase).toUpperCase(),
variant, variant,

View File

@ -482,6 +482,8 @@ TestRegister.addTests([
input: "0123456789ABCDEFFEDCBA9876543210", input: "0123456789ABCDEFFEDCBA9876543210",
expectedOutput: JSON.stringify({ expectedOutput: JSON.stringify({
mode: "Derive Session Key", mode: "Derive Session Key",
ksn: "FFFF9876543210E00001",
bdk: "0123456789ABCDEFFEDCBA9876543210",
ipek: "6AC292FAA1315B4D858AB3A3D7D5933A", ipek: "6AC292FAA1315B4D858AB3A3D7D5933A",
sessionBase: "042666B49184CFA368DE9628D0397BC9", sessionBase: "042666B49184CFA368DE9628D0397BC9",
variant: "None", variant: "None",