Re: Win32 Application CryptoAPI

From: Darren Bennett (darren_at_work.com)
Date: 11/29/04


Date: Sun, 28 Nov 2004 16:11:04 -0800

Hi Doug,

Thanks for your reply to my question.

I have modified the code to make it 128bit RC2 encryption as you suggested
but I still end up with the same result. I have included the updated code
below:

Win32 Application:
============
  HCRYPTPROV hProv;
  HCRYPTHASH hHash;
  HCRYPTKEY hKey;
  HANDLE hFile;
  DWORD dwNumBytes, dwBytesWritten;
  BYTE byPassword[] = {65, 66, 67, 68, 69, 70}; // equals "ABCDEF"
  BYTE byData[] = {10, 20, 30, 40, 50, 60, 70, 80, 0, 0, 0, 0, 0, 0,
0, 0};
  
  // Create the Cryptograhic Provider Object
  if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
    // Create a hash object
    if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
      // Hash in the password
      if (CryptHashData(hHash, byPassword, sizeof(byPassword), 0)) {
        // Derive a session key from the hash object.
        if (CryptDeriveKey(hProv, CALG_RC2, hHash, CRYPT_NO_SALT, &hKey)) {
          dwNumBytes = 8;
          if (CryptEncrypt(hKey, NULL, TRUE, 0, byData, &dwNumBytes,
sizeof(byData))) {
            // Create a file to store the encrypted data
            if ((hFile = CreateFile(_T("C:\\Encrypted.dat"), GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) !=
INVALID_HANDLE_VALUE) {
              // Write the encrypted data out to file
              WriteFile(hFile, &byData, dwNumBytes, &dwBytesWritten, NULL);
              // Close the file handdle
              CloseHandle(hFile);
            }
          }
          // Destroy the session key
          CryptDestroyKey(hKey);
        }
      }
      // Destroy the hash object
      CryptDestroyHash(hHash);
    }
    // Release the cryptographic provider context
    CryptReleaseContext(hProv, 0);
  }

C# Application:
==========
int iNumBytes;
FileStream fsData;
byte[] byData = new byte[16];
byte[] byInitVect = {0,0,0,0,0,0,0,0};
                        
// Open the file containing the encrypted data, read inb the data and close
the file
fsData = File.Open("C:\\Encrypted.dat", FileMode.Open);
iNumBytes = fsData.Read(byData, 0, byData.Length);
fsData.Close();
                        
// Derive a session key from the password using an MD5 hash
PasswordDeriveBytes SessionKey = new PasswordDeriveBytes("ABCDEF", null,
"MD5", 1);
                        
// Set up an RC2 cryptographic object
RC2CryptoServiceProvider Rc2 = new RC2CryptoServiceProvider();
Rc2.Mode = CipherMode.CBC;
Rc2.KeySize = 128;
Rc2.EffectiveKeySize = 128;
Rc2.BlockSize = 64;

// Decrypt the data
ICryptoTransform decryptor = Rc2.CreateDecryptor(SessionKey.GetBytes(16),
byInitVect);
byte[] myOutputBytes = new byte[decryptor.OutputBlockSize];
iNumBytes = decryptor.TransformBlock(byData, 0, decryptor.InputBlockSize,
myOutputBytes, 0);

Any help would be greatly appreciated.

Thanks,

- Darren -

"Doug Barlow" wrote:

> Darren,
>
> I haven't tried running your programs yet, but I do have a few suggestions.
>
> First, you've probably chosen the worst case algorithm for compatibility --
> The old Microsoft CSPs mess with 40-bit RC2 to try to make it stronger,
> giving it an 88-byte salt, so you've got to manage the salt values, too.
> You might have better luck moving up to a 128-bit RC2 key, which doesn't
> default to a special salt value. Take a look at the MSDN documentation for
> CryptDeriveKey for details.
>
> Next, I wouldn't assume the .NET PasswordDeriveBytes class derives the same
> key as the Win32 CryptDeriveKey service. In fact, I'd bet against it. You
> should come up with a common method for deriving a key, and make sure you
> use the same key and salt in both applications. You can import a plain-text
> session key into CryptoAPI by following the example shown in
> http://support.microsoft.com/default.aspx?scid=kb;en-us;228786.
>
> I hope that helps,
>
> Doug Barlow
> The Soft Pedal Shop
> http://www.softpedal.net
>
>
> "Darren Bennett" <darren@work.com> wrote in message
> news:167A699B-452A-4574-8FE4-00AE6ACBA4DC@microsoft.com...
> > Hi There,
> >
> > I have been scanning the newsgroups for a solution to my problem and have
> > found that a few others are also experiencing the same problem but none of
> > the solutions provided to them seem to work for me.
> > ...
>
>
>



Relevant Pages

  • Re: Convert PasswordDeriveBytes to String
    ... RijndaelManaged rijndaelCipher = new RijndaelManaged; ... PasswordDeriveBytes secretKey = new ... PasswordDeriveBytes(textBoxEncryptionPasspharse.Text, salt); ... ICryptoTransform encryptor = ...
    (microsoft.public.dotnet.security)
  • RE: Convert PasswordDeriveBytes to String
    ... This one's more of a security issue than an actual coding error. ... Here you're creating a salt that is probably only one or two bytes long (since it's ... >wondering how can I convert an PasswordDeriveBytes to String? ... >how do I display the "secretKey" into a TextBox? ...
    (microsoft.public.dotnet.security)
  • Re: PasswordDeriveBytes in .NET 2.0 Beta
    ... > derived with PasswordDeriveBytes. ... 'salt' is a byte array with length ... > 256 (identical in both CLRs of course) ... but the second array 'iv' is different. ...
    (microsoft.public.dotnet.security)
  • Re: Convert PasswordDeriveBytes to String
    ... Be careful with your salt generation method. ... you might use the random initial IV of the "rijndaelCipher" ... > |>Subject: Convert PasswordDeriveBytes to String ...
    (microsoft.public.dotnet.security)