I have this code in C++ (AnsiString is a wrapper for char* buffer):
BOOL HashIt(AnsiString &pw,BYTE *buf,BYTE &len)
{
HCRYPTPROV cp;
CryptAcquireContext(&cp,NULL,NULL,PROV_RSA_AES,CRYPT_VERIFYCONTEXT);
HCRYPTHASH ch;
CryptCreateHash(cp,CALG_MD5,0,0,&ch);
CryptHashData(ch,(BYTE*)pw.c_str(),pw.Length(),0);
HCRYPTKEY kc;
CryptDeriveKey(cp,CALG_3DES,ch,CRYPT_EXPORTABLE,&kc);
CryptExportKey(kc,NULL,PLAINTEXTKEYBLOB,0,buf,&dwLen);
len = (BYTE) dwLen;
}
So far I’ve got this far converting it to .NET:
public static byte[] HashItB(string text)
{
byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(text);
System.Security.Cryptography.MD5CryptoServiceProvider sp = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hashBytes = sp.ComputeHash(textBytes);
System.Security.Cryptography.PasswordDeriveBytes pdb = new System.Security.Cryptography.PasswordDeriveBytes(hashBytes, new byte[0]);
hashBytes = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, hashBytes);
// Need to export key as plain text blob here, CryptExportKey
return (hashBytes);
}
Assuming the above code is correct, my last step is to translate the CryptExportKey function to .NET. Can someone point me to the function or a sample? I can’t change the C++ method and I need my .NET code to match a legacy app. Or should I give up on .NET methods and either create a C++ DLL and call that (not crazy about that due to extra size of shipping another DLL with my tiny app), or pinvoke all of the Crypto functions?
The .NET method
PasswordDeriveBytes.CryptDeriveKey()is the equivalent to using the Win32 CryptoAPI method to hash the password, callCryptDeriveKeyand finally export the key by callingCryptExportKey.Your C++-code is equivalent to:
except that the .NET-code removes some header data from the exported key (a PLAINTEXTKEYBLOB-header). For a 192 bit 3DES key this is
"08 02 00 00 03 66 00 00 18 00 00 00". You can just prepend it in the .NET-code if you need it.