# Can I hash a secret key and used the hash as key ID?

I am using AES-CBC to provide confidentiality for protocol messages. I want to allow the receiver to know the secret key by using a key ID. For this I hash the secret key to generate a key ID. Every time the sender wants to send a message, the sender appends the key ID to the message to allow the receiver to bind the key ID with a secret key.

Is hashing the secret key to generate a key ID a secure mechanism?

• So you're essentially looking for an AES equivalent of an RSA public key fingerprint? Aug 31 '18 at 1:35
• Beware that an attacker may change the key ID and indicate a different, possibly less secure key. If you leave an insecure test key or similar you may be in trouble. If you use CBC (especially without additional protection from HMAC) I would seriously question the security of your protocol, up to and including the confidentiality of the messages. Aug 31 '18 at 1:54
• The chat app Telegram has a symmetric 256 byte key (authkey) between client and server and it uses 8 bytes of its SHA-1 hash as a key identifier. Aug 31 '18 at 22:17

In the standard model of hash functions there isn't a requirement that hash outputs not have properties that leak information about the input.

In the random oracle model of hash functions there isn't a relationship between input and output other than the input/output mapping you get from querying the oracle. The model says that for each input the corresponding output is assigned a value chosen randomly from a uniform distribution of all possible output values.

If a hash function behaves like a random oracle then the only way to learn about an input with just the output known to you is to try hashing inputs and look for matching results. (This is how password cracking works against defenders who use salts properly.)

How secure it would be to publish such a hash output depends on how unpredictable the input is. For low entropy (highly predictable) inputs, the number of hashes you need to compute in this guess-and-check method is small (or likely to be small). For high entropy inputs the number of evaluations is large.

If your input can be one of $2^{128}$ possible values and each possible value is equally probable, then the expected (or maximum) number of hashes that need to be tested is about $2^{127}$ (or $2^{128}$).

Your AES key is supposed to be unpredictable and come from a uniform distribution of all $2^{128}$ possible keys (or more for larger key sizes). Therefore if you publish only the hash of an AES key, people won't be able to learn anything about the key without on the order of $2^{127}$ brute-force-effort. The same amount of work it would take to guess an AES key by brute force attack.

People treat cryptographic hashes (like the SHA and Blake2 algorithms) like a random oracle in practice. (Information can still be leaked through side-channels of implementations, of course.) So publishing the SHA-2 hash of a secret key doesn't compromise security on it's own. Not anymore than publishing the cryptographic hash of any kind of secret with at least 128-bit entropy.

HOWEVER that doesn't mean your specific protocol or application won't use the hash of a secret key securely. As @RichieFrame said some other part of some software could be using the hash of the key differently, so it's risky. And as @MaartenBodewes says the key ID mechanism could be a security risk itself.

You also must not use a non-cryptographic hash.

I suggest you use a separate randomly generated key-ID instead of something derived from the key, if possible, to avoid potential errors.

• IDs don't need to be randomly generated. Sequentially is fine if you are working in an entropy-constrained environment (but you do then have to worry about duplicate IDs if the source is restarted). Aug 31 '18 at 11:56

I would do it a little differently so there is less of a relationship between the ID and the key

Encrypt a block of all 0s with the key; $X$ = $E_k(0_{128})$

Hash X; $H$ = SHA256$(X)$

Truncate the hash to 32 bits (8 hex characters)

Encrypting a block of 0s and truncating is generally how a key check value is generated, as block ciphers are designed to resist key recovery, the intermediate hash step is there for extra security, so you are not exposing a known ciphertext value.

I would not consider a direct key hash safe, some software may use that internally, and you do not want that exposed

• What do you mean by 0s? Aug 31 '18 at 1:32
• @AymnAlaney 0 bits, AES has a 128-bit block size, so all of them 0 and not 1 Aug 31 '18 at 1:47
• If software was to use a hash over a secret key internally other than to identify the key I would consider the software broken. But I like the idea to add an additional hash over the regular KCV, which has broad support but may indeed be insecure... Aug 31 '18 at 1:50

Hashing does not provide confidentiality, and theoretically your scheme is broken.

PS: This is exact and correct answer to the OP question, and I will not delete it. Please downvote to show your cryptographic illiteracy.

• 1) Maybe remove the outright anger from your answer? 2) Maybe add some more context? I suspect the downvotes are because a one-sentence answer (correct or otherwise) is not explaining anything. Aug 31 '18 at 10:53