As you said, CryptDeriveKey() has some "specific" indeed :) If it obtains a key (from the hash object) with a smaller length than required, then it applies some extra steps to derive the key.
http://msdn2.microsoft.com/en-us/library/aa379916.aspx wrote: > > Let n be the required derived key length, in bytes. The derived key is the > first n bytes of the hash value after the hash computation has been > completed by CryptDeriveKey. If the required key length is longer than the > hash value, the key is derived as follows: > > 1. Form a 64-byte buffer by repeating the constant 0x36 64 times. Let k > be the length of the hash value that is represented by the input parameter > hBaseData. Set the first k bytes of the buffer to the result of an XOR > operation of the first k bytes of the buffer with the hash value that is > represented by the input parameter hBaseData. > 2. Form a 64-byte buffer by repeating the constant 0x5C 64 times. Set > the first k bytes of the buffer to the result of an XOR operation of the > first k bytes of the buffer with the hash value that is represented by the > input parameter hBaseData. > 3. Hash the result of step 1 by using the same hash algorithm as that > used to compute the hash value that is represented by the hBaseData > parameter. > 4. Hash the result of step 2 by using the same hash algorithm as that > used to compute the hash value that is represented by the hBaseData > parameter. > 5. Concatenate the result of step 3 with the result of step 4. > 6. Use the first n bytes of the result of step 5 as the derived key. > Actually, the first 16 bytes of the key, produced by EVP_BytesToKey() are equal to hash value of CryptoAPI hash object after CryptDeriveKey() returns. So, the following simple function must produce the same derived key as CryptDeriveKey() does. Here keyOpenSSL raw is identical to hash object value and its length in my case is 16 bytes. int Win32DeriveKey(const unsigned char* keyOpenSSL, unsigned long lenOpenSSL/*=16*/, unsigned char* keyWin32, unsigned long lenWin32) { unsigned char buf1[64]; unsigned char buf2[64]; std::fill_n(buf1, _countof(buf1), 0x36); std::fill_n(buf2, _countof(buf2), 0x5C); for (unsigned long i = 0; i < lenOpenSSL; ++i) { buf1[i] ^= keyOpenSSL[i]; buf2[i] ^= keyOpenSSL[i]; } unsigned char bufmd5[2 * MD5_DIGEST_LENGTH]; MD5(buf1, _countof(buf1), bufmd5); MD5(buf2, _countof(buf2), bufmd5 + MD5_DIGEST_LENGTH); memcpy(keyWin32, bufmd5, std::min(_countof(bufmd5), lenWin32)); return 1; } The results are amazing to me. CryptoAPI derived key ca ee 31 f5 5e d5 65 00 e9 60 c2 eb 79 58 68 b8 b6 fd d5 26 8d 3c 21 f7 cb ef 31 f4 5e d5 64 01 e9 61 c2 ea 79 58 68 b9 b6 fd d5 26 8c 3d 20 f7 keyWin32 value As you can see, these keys are a little bit equal. :) But... the 3DES-ciphers are equal! What does it mean? Why do 3DES algorithm of CryptoAPI and 3DES algorithm of OpenSSL produce the same cipher by different keys? :confused: Dr. Stephen Henson wrote: > > On Thu, Oct 25, 2007, MaxAndr wrote: > >> >> >> Kiefer, Sascha wrote: >> > >> > if you use the unsimplefied version of the cryptoapi you have to >> reverse >> > the bytes auf your results before using them. >> > >> >> I'm not sure that the translation is correct at all. Since the derived >> keys >> and the encrypted data are completely different. >> >> If EVP_BytesToKey() gives not appropriable key then may be I should try >> some >> other functions. I have read about >> http://www.openssl.org/docs/crypto/EVP_BytesToKey.html EVP_BytesToKey() >> that >> "Newer applications should use more standard algorithms such as PKCS#5 >> v2.0 >> for key derivation". >> >> Which of them should I use? >> >> > > None of them. CryptDeriveKey() doesn't have a direct equivalent in OpenSSL > for > 3DES keys. > > I can't remember the details but CryptDeriveKey() does something different > when the message digest doesn't provide enough keying material. Do a > search on > the web somewhere. > > EVP_BytesToKey() does non standard things too in such circumstances which > is > why things like PKCS#5 v2.0 are recommended for new applications. > > However that wont help with your case. > > You have several options. > > One is to use the exponent of one hack in CryptoAPI to use a raw key (see > MS > knowledge base). > > Alternatively you can write an implementation of CryptDeriveKey() based on > OpenSSL functions (digests). > > Steve. > -- > Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage > OpenSSL project core developer and freelance consultant. > Funding needed! Details on homepage. > Homepage: http://www.drh-consultancy.demon.co.uk > ______________________________________________________________________ > OpenSSL Project http://www.openssl.org > User Support Mailing List openssl-users@openssl.org > Automated List Manager [EMAIL PROTECTED] > > -- View this message in context: http://www.nabble.com/DES3%3A-Windows-CryptoAPI-and-OpenSSL-tf4689809.html#a13427321 Sent from the OpenSSL - User mailing list archive at Nabble.com. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]