none
Migrating from CryptoAPI to System.Security.Cryptography RRS feed

  • Question

  • Hi,

    I have two functions that use the Win32 Crypto API to encrypt/decrypt arbitrary bytes using an arbitrary password. I am trying to reproduce these functions in .NET, but the I'm stuck trying to find an equivalent to the "CryptDeriveKey" function.  Below I've pasted the decryption function. Can someone help me translate this into .NET?

    Thanks,
    Sean

    BOOL __stdcall IQDecrypt(LPBYTE pData, LPDWORD pdwSize, LPCTSTR pszPassword, LPTSTR* ppszBuffer)
    {
        HCRYPTPROV hProv = NULL;
        HCRYPTHASH hHash = NULL;
        HCRYPTKEY hKey = NULL;

        // Check parameters
       
        *ppszBuffer = NULL;

        ::CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);

        // Get a hash object
        ::CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);

        // Hash our password
        ::CryptHashData(hHash, (LPBYTE)pszPassword, ::_tcslen(pszPassword), 0);
       
        // Derive our key from the password
        ::CryptDeriveKey(hProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey);

        // Create buffer and copy the original
        *ppszBuffer = new TCHAR[*pdwSize];
        ::memcpy(*ppszBuffer, pData, *pdwSize);
       
        // Decrypt the data
        ::CryptDecrypt(hKey, NULL, TRUE, 0, (LPBYTE)*ppszBuffer, pdwSize);

        // Release hash object.
        ::CryptDestroyHash(hHash);

        // Release the key object.
        ::CryptDestroyKey(hKey);
       
        return TRUE;
    }

    Thursday, January 6, 2011 2:41 PM

Answers

  • Here is a simply demo about encrypt/decrypt using C#, hope it could be useful for you:

    using System;

    using System.IO;

    using System.Security.Cryptography;

    using System.Text;

     

    namespace CryptDemo

    {

        public class CryptHelper

        {

            private UTF8Encoding encoder = new UTF8Encoding();

     

            private Rfc2898DeriveBytes KeyGen(string HashCombination)

            {

                byte[] saltBytes = encoder.GetBytes("Constants.SaltString");

                return new Rfc2898DeriveBytes(HashCombination, saltBytes);

            }

     

            private SymmetricAlgorithm CreateAlgorithm(string password)

            {

                string HashCombination = "Constants.HashKey" + password;

     

                RijndaelManaged alg = new RijndaelManaged();

                alg.Padding = PaddingMode.PKCS7;

     

                Rfc2898DeriveBytes key = KeyGen(HashCombination);

     

                alg.Key = key.GetBytes(Convert.ToInt32(alg.KeySize / 8));

                alg.IV = key.GetBytes(Convert.ToInt32(alg.BlockSize / 8));

     

                return alg;

            }


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 1:25 AM
  •         public byte[] Encrypt(string plainText, string password)

            {

                if (plainText == null || plainText.Length <= 0)

                {

                    throw new ArgumentNullException("plainText is null");

                }

     

                MemoryStream msEncrypted = null;

     

                SymmetricAlgorithm alg = CreateAlgorithm(password);

                try

                {

                    ICryptoTransform encryptor = alg.CreateEncryptor(alg.Key, alg.IV);

     

                    msEncrypted = new MemoryStream();

                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypted, encryptor, CryptoStreamMode.Write))

                    {

                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))

                        {

                            swEncrypt.Write(plainText);

                        }

                    }

                }

                finally

                {

                    if (alg != null)

                    {

                        alg.Clear();

                    }

                }

     

                return msEncrypted.ToArray();

            }

     

            public string Decrypt(byte[] cipherText, string password)

            {

                if (cipherText == null || cipherText.Length <= 0)

                {

                    throw new ArgumentNullException("cipherText is null");

                }

     

                string plaintext = null;

     

                SymmetricAlgorithm alg = CreateAlgorithm(password);

                try

                {

                    ICryptoTransform decryptor = alg.CreateDecryptor(alg.Key, alg.IV);

     

                    using (MemoryStream msDecrypt = new MemoryStream(cipherText))

                    {

                        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))

                        {

                            using (StreamReader srDecrypt = new StreamReader(csDecrypt))

                            {

                                plaintext = srDecrypt.ReadToEnd();

                            }

                        }

                    }

                }

                finally

                {

                    if (alg != null)

                    {

                        alg.Clear();

                    }

                }

     

                return plaintext;

            }

        }

    }


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 1:25 AM
  • Hi,

    You can use the TripleDESCryptoServiceProvider Class

    We are also using this Triple DES,
    This one can communicate with different platforms as well like we are using
    from .net to Java or JSP.

    Find the Article at MSDN.


    COURTECY : MSDN
    http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider(v=VS.71).aspx


    Regards,
    RajeshS.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 12:33 PM

All replies

  • Here is a simply demo about encrypt/decrypt using C#, hope it could be useful for you:

    using System;

    using System.IO;

    using System.Security.Cryptography;

    using System.Text;

     

    namespace CryptDemo

    {

        public class CryptHelper

        {

            private UTF8Encoding encoder = new UTF8Encoding();

     

            private Rfc2898DeriveBytes KeyGen(string HashCombination)

            {

                byte[] saltBytes = encoder.GetBytes("Constants.SaltString");

                return new Rfc2898DeriveBytes(HashCombination, saltBytes);

            }

     

            private SymmetricAlgorithm CreateAlgorithm(string password)

            {

                string HashCombination = "Constants.HashKey" + password;

     

                RijndaelManaged alg = new RijndaelManaged();

                alg.Padding = PaddingMode.PKCS7;

     

                Rfc2898DeriveBytes key = KeyGen(HashCombination);

     

                alg.Key = key.GetBytes(Convert.ToInt32(alg.KeySize / 8));

                alg.IV = key.GetBytes(Convert.ToInt32(alg.BlockSize / 8));

     

                return alg;

            }


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 1:25 AM
  •         public byte[] Encrypt(string plainText, string password)

            {

                if (plainText == null || plainText.Length <= 0)

                {

                    throw new ArgumentNullException("plainText is null");

                }

     

                MemoryStream msEncrypted = null;

     

                SymmetricAlgorithm alg = CreateAlgorithm(password);

                try

                {

                    ICryptoTransform encryptor = alg.CreateEncryptor(alg.Key, alg.IV);

     

                    msEncrypted = new MemoryStream();

                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypted, encryptor, CryptoStreamMode.Write))

                    {

                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))

                        {

                            swEncrypt.Write(plainText);

                        }

                    }

                }

                finally

                {

                    if (alg != null)

                    {

                        alg.Clear();

                    }

                }

     

                return msEncrypted.ToArray();

            }

     

            public string Decrypt(byte[] cipherText, string password)

            {

                if (cipherText == null || cipherText.Length <= 0)

                {

                    throw new ArgumentNullException("cipherText is null");

                }

     

                string plaintext = null;

     

                SymmetricAlgorithm alg = CreateAlgorithm(password);

                try

                {

                    ICryptoTransform decryptor = alg.CreateDecryptor(alg.Key, alg.IV);

     

                    using (MemoryStream msDecrypt = new MemoryStream(cipherText))

                    {

                        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))

                        {

                            using (StreamReader srDecrypt = new StreamReader(csDecrypt))

                            {

                                plaintext = srDecrypt.ReadToEnd();

                            }

                        }

                    }

                }

                finally

                {

                    if (alg != null)

                    {

                        alg.Clear();

                    }

                }

     

                return plaintext;

            }

        }

    }


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 1:25 AM
  • Hi,

    You can use the TripleDESCryptoServiceProvider Class

    We are also using this Triple DES,
    This one can communicate with different platforms as well like we are using
    from .net to Java or JSP.

    Find the Article at MSDN.


    COURTECY : MSDN
    http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider(v=VS.71).aspx


    Regards,
    RajeshS.

    • Marked as answer by eryang Monday, January 17, 2011 6:38 AM
    Friday, January 7, 2011 12:33 PM