# Using hash functions for Key Check Values (KCV)

As discussed in this post, calculating key check values for block cipher keys can introduce vulnerabilites. Plus, this method only applies for block ciphers, and there is no equivalence for private keys used for asymmetric cryptography (although an alternative is given in an answer of this post, the KCV size is huge in this case).

Would it be relevant to compute a hash over the key (with SHA-2 or any other secure cryptographic hash function) and to consider the $n^{\text{th}}$ first bytes ($n = 3$ for example)? Or could it introduce weaknesses in some specific cases?

• $HMAC_{[Enc_k(00_{16}) \ \oplus \ Enc_k(FF_{16})]}("$KCV$")$ truncated to a few bytes would keep the key from being used directly, is easy to describe algorithmically, is friendly with HSMs and implementations where you do not have direct access to the key, is friendly to all standard modes including GCM, and is non-invertible. This is for symmetric of course, but is adaptable to asymmetric in some cases Aug 4 '16 at 0:37

Yes, creating a hash over the key is actually a common method of creation of KCV's (outside of encrypting a block of zero bytes). Obviously, just like a KCV created by encrypting zero's, you might want to make sure that it isn't used the same way in your protocol. As HMAC uses additional input, this is not very likely. That said, it might be trickier for SHA-3 / KMAC (!).

The disadvantage of using a hash is that the bytes of a symmetric key may only be available for encryption. This could for instance be the case if the key is stored in hardware. So in that case you'd still need to use a scheme based on the block cipher itself.

For private / public keys it is common to use a hash over the modulus. The modulus is unique for the key pair, so a hash over the modulus is a fine KCV that works for both the private key, public key and therefore certificate.

• OK, giving away one of my fine ideas here (as I still haven't written the frickin` paper for it): you could use a KDF over a known (unlikely, but static) string and optionally a salt using the key as input and use the output of that as KCV. You could use a KDF based on HMAC or a symmetric cipher depending on the type of the key. Aug 3 '16 at 22:10

To answer this question, the first thing is consider is "why do we have a key check value at all? What benefit do we hope to gain from it?"

From my perspective, it would appear that the main use of a KCV is to quickly catch it when we attempt to decrypt a message with the wrong key. This implies:

• It makes sense only if attempting to decrypt the message with the wrong key is a plausible occurance. The main case where this makes sense is if you are assuming the user will manually enter the key or the seed to generate the key (and might typo it).

• It makes sense only if it is necessary for you to quickly detect an incorrect key. Normally, we strongly suggest that when you encrypt, you include some sort of integrity check (as there are a number of clever methods known where an attacker modifies the ciphertext, and learns something from how the decryptor reacts when it decrypts it); if you enter the wrong key, presumably the integrity check would fail, and you'd notice that the key is wrong. So, the only real value a KCV would bring is that you can determine whether the key is correct quickly (before decrypting the potentially large file).

Now, if the key is low entropy (which a manually entered key or key seed would be), a KCV would make it easier on the attacker to do a brute force search; instead of decrypting the entire file and seeing if it works, he could just check the KCV, and reject most of the incorrect entries in the database. You could try to slow him down by using, say, Argon2 to generate the KCV, however that'd void the entire reason you have a KCV in the first place.

With that background in mind, lets go over your questions:

Would it be relevant to compute a hash over the key and to consider the $n$th first bytes

If you actually need a KCV (see above for why it is only occasionally appropriate), then this would work (assuming, of course, that you don't use the hash of the key for anything else; if you do, you'll run into exactly the same issues that Maarten warned you about). So, yes, this could introduce a weakness, if (for example) you are using $SHA-2(password)$ to encrypt the first several bytes of your file.

And, for a block cipher, encrypting a block of all 0's, and using a few bytes from that, would work as long as the cipher block mode you use doesn't rely on the encryption of the all 0's block; for example, counter mode standard at a random nonzero counter would work; also CBC mode with a random IV would also work.

General rule: if you use the password in multiple ways, you need to consider that those multiple ways play nicely together, and the one usage doesn't leak information that the other usage needs to keep secret.

there is no equivalence for private keys used for asymmetric cryptography

Actually, if you don't mind leaking who you're encrypting the message to (in my experience, you usually don't; if I email an encrypted message with Alice with Alice's public key, well, Alice's email address will appear in the SMTP header), then it's easy; just hash the public key and that's the KCV. Alice knows her own public key, and so should be able to recognize the hash of it (and reject any encrypted message with a different hash).