-1

I am integrating with 3rd party software that uses AES 128 encryption. I know this is not ideal, but the choice of encryption is up to the 3rd party software. I am using C#.

My problem is in deriving the key from the password. The third party has told me that the key is generated using the CryptoAPI's CryptDeriveKey. I have tried both the PasswordDeriveBytes and the RFC2898DeriveBytes implementations of this in .NET, but it seems like neither one supports AES key generation anymore.

I have tried to implement PBKDF1 myself, but it doesn't match the hash that the third party has given me.

The third party has given me a tool to check my encryption, and they say that the password "my_key" should hash to "13606B772B52B5F83BE4FF04572EB8" which unfortunately seems to have a byte cut off in their ui.

So, finally, I was wondering if anyone knew how to implement PBKDF1 by hand in C#, using a SHA1 hash, where the key "my_key" would hash to "13606B772B52B5F83BE4FF04572EB8XX".

Juding by their documentation, the CryptDeriveKey IV is 0 and there is no salt.

1 Answers1

0

Microsoft has an obscure subsection in the documentation for the CryptAPI (C++) version of CryptDeriveKey that describes an algorithm to derive a key.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379916%28v=vs.85%29.aspx.

In C#, it turned out to be this:

using (SHA1 sha1 = SHA1.Create()) {

            // The following algorithm is taken from:
            // <link>http://msdn.microsoft.com/en-us/library/windows/desktop/aa379916%28v=vs.85%29.aspx</link>
            byte[] baseData = sha1.ComputeHash(Encoding.UTF8.GetBytes(plaintextPassword));
            byte[] buffer1 = new byte[64];
            byte[] buffer2 = new byte[64];

            for (int i = 0; i < 64; i++) {
                buffer1[i] = 0x36;
                buffer2[i] = 0x5C;
                if (i < baseData.Length) {
                    buffer1[i] ^= baseData[i];
                    buffer2[i] ^= baseData[i];
                }
            }

            byte[] buffer1Hash = sha1.ComputeHash(buffer1);
            byte[] buffer2Hash = sha1.ComputeHash(buffer2);

            return buffer1Hash.Concat(buffer2Hash).Take(_keySize / 8).ToArray();

}