9

Simple question: we have AES 128 encryption and a key. How can we calculate the key check value (KCV)?

One example: key is 48C3B4286FF421A4A328E68AD9E542A4 and KCV should be 77DC84.

I am trying it out in C#, but there are just to many 'unknowns' for a newbie in cryptography...

Edit: there was a question why I need it - let's say that I have a bunch of key-KCV combinations, written down by multiple users in our organization, but some of the keys are invalid (employee wrote 8 instead of B, 1 instead of 7, etc...). So I needed a program, which changes some bytes in the key and then calculates the KCV. If the key has one wrong byte, then it is calculated in 2ms, for two wrong bytes 5seconds, for three wrong bytes an hour and half, and so on...

sventevit
  • 244
  • 1
  • 2
  • 7

2 Answers2

3

To calculate the KCV for AES, you take the first three bytes of the encryption of zero under your key.

Indeed, the case you've given is precisely this - the zero vector encrypted under the key 48C3B4286FF421A4A328E68AD9E542A4 is 77dc841daeb43315fed9acdf2f965f45, which restricts to 77dc84.

In your question you say you already have AES-128 encryption, at which point calculating the KCV shouldn't be a problem. I won't ask why you're calculating a KCV, but be warned that there may well be better ways to achieve your actual goal. The other article with this tag provides a reasonable discussion about the benefits of them.

Cryptographeur
  • 4,317
  • 2
  • 27
  • 40
0

If anyone needs it, C# code to calculate the KCV (you need only the first three bytes of the GetKcv return value):

class Aes
{
    private readonly byte[] _iv;
    private readonly int _secretLength;
    private readonly byte[] _secret;
    private readonly RijndaelManaged _cryptoEngine;

    public Aes()
    {
        _iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        _secretLength = 8;
        _secret = new byte[_secretLength];
        for (int i = 0; i < _secretLength; i++)
        {
            _secret[i] = 0;
        }

        _cryptoEngine = new RijndaelManaged
        {
            Padding = PaddingMode.Zeros,
            Mode = CipherMode.ECB,
            KeySize = 128,
            BlockSize = 128
        };
    }

    public byte[] GetKcv(byte[] key)
    {
        byte[] result;
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, _cryptoEngine.CreateEncryptor(key, _iv), CryptoStreamMode.Write))
            {
                cryptoStream.Write(_secret, 0, _secretLength);
                cryptoStream.FlushFinalBlock();

                result = memoryStream.ToArray();
            }
        }

        return result;
    }
}
sventevit
  • 244
  • 1
  • 2
  • 7