I have a number of questions regarding Key Serial Numbers (KSNs) in DUKPT:

  1. KSNs are 8 - 10 bytes long. Older implementation are 8 bytes whereas newer ones are 10 bytes. Do I risk being incompatible with some old system if I create 10 bytes long KSNs?
  2. KSNs have 3 components: a 21 bits transaction counter and remaining bits are for key set ID and Tamper Resistant Security Module (TRSM) ID. For an 8 byte KSN the typical convention is 24 bits for key set ID and 19 bits for TRSM ID. This means around 16M Base Derivation Keys (BDKs) and 500K devices. To me this allocation has pros and cons. The cons are that I will never have 16M BDKs and if the business is successful it is quite possible to have > 500K devices. The advantage is that it forces us to not use the same BDK on more than 500K devices which limits exposure of one BDK being compromised. I do read that there is flexibility in how many bits are allocated to key set ID vs TRSM ID. So I'm tempted to swap the allocation such that we can have up to 500K BDKs and 16M devices. But I also see many open source implementations of DUKPT that assume 24-19-21 bits split. Those implementations would all break if I don’t follow the convention. Would you recommend that I just stick to convention?
  3. Is there some standard way for setting the key set IDs or does every entity owning a BDK come up with its own convention? Can I assign key set ID = 1 to my very first BDK ever and then increment it by 1 for each new BDK? Or is that strategy too naive?
  4. Is there some standard way for setting the TRSM ID? Can I assign TRSM ID = 1 for the very first device injected using a new BDK and then increment it by 1 for each new BDK?
  1. 8/10 bytes. The standard has always had KSN 10 bytes (80 bits), but allowed smaller values padded on the left with 0xFF, and many people did or do use 8 bytes. I'm not in a position to say there's a clear pattern either way. If any of the devices (or systems) you expect to deal with are limited to 8 bytes, then yes use 8 bytes. As below, it's basically arbitrary now anyway.

  2. You're right nearly everyone seems to use xx-19-21 bits which for 8 bytes is 24-19-21 bits. Remember DUKPT was originally designed for ATMs that cost many thousands of dollars, so 512K wasn't a troublesome limit; now people use it for matchboxes. Technically only the counter part (xx-21) matters to the encryption so you can shift the other boundary(ies?) if your programs, APIs, partners etc. can handle it. OTOH if you stick to convention, which is easier, nothing says different KSIs must always map to different BDKs. You can have [FFFF]ABAB00-mmmmm is the first 512K devices for BDK A, ABAB01-mmmmm is the second 512K, etc., ABAB50 is the first batch for BDK B, etc. As long as you only need to manage tens or maybe a hundred batches (50+ million devices) this is fine. If you needed much more than 500+ million then I'd worry about it, but by then you'd have enough clout to change this.

  3. Originally the idea was that KSI would identify the bank or subpart of a bank (ATMs, remember) and be globally unique so any cryptogram in the clearing network would self-identify/verify who it "belongs to". Nowadays KSI has basically become arbitrary, so yes pick what you like. Except I suggest don't use a value that has leading zeros; too many things tend to think leading zeros on a number-looking (even hex-looking) value are not significant and drop them.

  4. TRSM ID (or device id): yes just use sequential numbers. But beware you often are shown the 21-19 bits displayed in hex like -00000-ttttt and -00001-ttttt are device 0, -00002-ttttt plus are device 1, ... -FFFFE-ttttt plus are device 0x7FFFF.

Your Answer

