I have a system where a block cipher key (likely AES) is entered via a 'command line' over a serial console, probably as hex. The system has no 'print key' feature, so the key is hopefully 'ingest only'.

I was considering offering a 'output of known test vector V with new key K and known/fixed IV is X', where X is printed over the console. This would give the key installer confirmation that the key had been transcribed correctly, since they would compare X with a pre-computed version. V could be e.g. the standard AES test vector 00 01 .. 0F. Its length would be 16 bytes, matching the cipher's block length.

So, although the key itself is not readable from the system, an output that USED the key is, in X. V is then a 'known plaintext'.

Is such a feature a bad idea? Does it allow an adversary, who might snatch the system, to obtain the key any faster than if the feature had not been present?

For now, I don't want to consider any other avenues the attacker might have to physically break into the system, I just want to consider the known plaintext question.


What you're trying to do is to construct a Key Check Value or KCV.

Your scheme is dangerous, as you don't know if such a plaintext is used somehow. For instance, imagine using an all zero plaintext to create a KCV (like many HSM's do) and then using the key for counter mode. If the nonce starts at zero, then the counter block is all zero as well. Now your KCV contains (part of) the key stream, letting an attacker decrypt ciphertext.

What you could do is to establish a 128 bit constant value using a random number generator and then use that value as salt (or label) for a KDF, which uses the key as input keying material. You could use "DO NOT USE" or something similar as label for the Info parameter. That way you get a Key Check Value that is certainly not used in any protocol.

Or, slightly less secure but a lot easier, just use a SHA-256 hash over the key as KCV. It's a one way function, and the SHA-256 hash over the key is generally never used. If you mix that with a salt and a label (using concatenation) it becomes even less likely to be used as sometimes SHA-256 is used as a poor man's KDF (which is what we're doing here).

  • 1
    $\begingroup$ I wouldn't use a plain SHA256(key) either. You never know when someone is going to decide to use the key for a hash-based KDF… Use something like SHA256("key check value 1:" + key). $\endgroup$ – Gilles 'SO- stop being evil' Jun 2 at 21:13
  • $\begingroup$ Yeah, adding a label or something similar works fine. $\endgroup$ – Maarten Bodewes Jun 2 at 22:03
  • $\begingroup$ Yes, I see how just hash(key), e.g. sha256(key) is sensible. It avoids any encryption at all, so is not susceptible to a garbled/mismatched IV for example. Really, all I am trying to do is assert to the user that the key entered is actually what was thought to be entered. A one-way function like a hash is perfect. I'm not fully understanding why an extra label is needed? It complicates things a bit, since I have to program it into the system AND inform the customer (the entity that installs the key) of this label. $\endgroup$ – tobermory Jun 3 at 0:20
  • $\begingroup$ It's because other parts of the protocol may use the same construction. If you allow an attacker to see the result, and you also derive a session key in the same way then you would obviously have a problem. If that's not the case you could just use the key as input. But adding a label would not really slow you down much if any. Cryptographers tend to rely on constructions that are always secure, because we know the pitfalls. $\endgroup$ – Maarten Bodewes Jun 3 at 7:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.