-1
votes
$\begingroup$

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.

$\endgroup$
  • 1
    $\begingroup$ I don't really understand what your question is. $\endgroup$ – mikeazo Feb 9 '16 at 0:13
  • $\begingroup$ Microsoft does document their "CryptDeriveKey" function. Check msdn. It's their own invention, not standard based. $\endgroup$ – Henno Brandsma Feb 9 '16 at 8:12
0
votes
$\begingroup$

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();

}
$\endgroup$

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