请问调用c#中md5类的算法加密时它的默认salt值是多少?

时间:2022-10-28 18:20:24
我做了两个系统,一个是用asp.net的论坛,一个是用vc++.net的atl server做的社区,现在想把两个系统的登陆统一起来,都用md5加密。
论坛用的是调用md5 class的ComputeHash方法直接生成的。
现在想在c++中也用md5加密和c#里统一起来。
atl server的c++不是托管代码所以不支持md5 class的ComputeHash方法直接生成。

现在问题是C#中md5 class的ComputeHash方法直接生成密码时,它默认的salt是多少(因为数据库中不需要保存salt,所以肯定不是随机生成的)谢谢各位大侠。

6 个解决方案

#1


http://www.obviex.com/samples/EncryptionWithSalt.aspx

#2


Md5算法已经被破解,不要再用它了。用SHA1吧。

#3


SHA1也不远了

#4


Visual C++ 概念:添加功能   

确保用户密码的安全
在这一步中,您将创建一些 Helper 函数以简化散列和比较密码的过程。这些代码将使用 ATL Server 提供的加密类。

为加密的 Helper 函数创建新的头文件 

在解决方案资源管理器中,右击 Tutorial 项目。 
在快捷菜单上,单击“添加”,然后单击“添加新项”。 
将出现“添加新项”对话框。 

在“模板”窗格中,单击“头文件 (.h)”,并在“名称”框中输入“Encrypt.h”。 
单击“打开”。 
Visual Studio 在磁盘上创建文件并将它添加到您的项目中。 

将下列代码添加到 Encrypt.h: 
#pragma once

#include <atlcrypt.h>

namespace VCUE
{
   inline HRESULT EnsureAcquire(
         CCryptProv& prov,
         LPCTSTR pszContainer = NULL,
         LPCTSTR pszProvider = MS_DEF_PROV,
         DWORD dwProvType = PROV_RSA_FULL,
         DWORD dwFlags = CRYPT_VERIFYCONTEXT | CRYPT_SILENT
         )
   {
      HRESULT hr = prov.Initialize(dwProvType, pszContainer, 
      pszProvider, dwFlags);

      if (hr == NTE_KEYSET_NOT_DEF)
            hr = prov.Initialize(dwProvType, pszContainer, pszProvider,
                                            dwFlags | CRYPT_NEWKEYSET);

      return hr;
   }
}
EnsureAcquire 是初始化加密提供程序(一个提供加密函数的对象)的 Helper 函数。该函数通过设置下面两个标记,提供用于服务器应用程序的灵敏默认参数:一个是禁用加密提供程序可能向用户显示的任何用户界面的标记 (CRYPT_SILENT),另一个是通知提供程序不需要访问私钥的标记 (CRYPT_VERIFYCONTEXT)。该函数还确保在初始化因容器不存在而失败时尝试创建容器。有关更多信息,请参见 CCryptProv::Initialize。将下列代码添加到 Encrypt.h: 

   inline HRESULT CreateSaltedHash(
            CCryptProv& Provider,
            const BYTE* Secret, DWORD SecretLength,
            const BYTE* Salt, DWORD SaltLength,
            BYTE* Hash,   DWORD& HashLength
         )
   {
      HRESULT hr = E_FAIL;
      HCRYPTHASH hHash = 0;
      if (CryptCreateHash(Provider.GetHandle(), CALG_MD5, 
          0, 0, &hHash))
      {
         CCryptHash oHash(hHash, TRUE);
         hr = oHash.AddData(Secret, SecretLength);
         if (SUCCEEDED(hr))
         {
            hr = oHash.AddData(Salt, SaltLength);
            if (SUCCEEDED(hr))
            {
               DWORD Size = 0;
               hr = oHash.GetSize(&Size);
               if (SUCCEEDED(hr))
               {
                  if (Size <= HashLength)
                     hr = oHash.GetValue(Hash, &HashLength);
                  else
                     hr = E_OUTOFMEMORY;
               }
            }
         }
      }

      return hr;
   }
CreateSaltedHash 使用 MD5 哈希算法从机密(如密码)和 salt(一个随机数)生成哈希。这些代码创建 CCryptHash 对象,将机密和 salt 添加到哈希,然后在调用方所提供缓冲区的大小可以容纳哈希值时获取该值。将下列代码添加到 Encrypt.h: 

   inline HRESULT HashSecret(
            const BYTE* Secret, DWORD SecretLength,
            BYTE* Salt, DWORD& SaltLength,
            BYTE* Hash, DWORD& HashLength
            )
   {
      CCryptProv Provider;
      HRESULT hr = EnsureAcquire(Provider);
      if (SUCCEEDED(hr))
      {
         hr = Provider.GenRandom(SaltLength, Salt);
         if (SUCCEEDED(hr))
         {
            hr = CreateSaltedHash( Provider,
                  Secret, SecretLength,
                  Salt, SaltLength,
                  Hash, HashLength);
         }
      }
      return hr;
   }
HashSecret 获取机密并返回 salt 以及通过合并机密和 salt 所生成的哈希。它包装获取加密提供程序所需的调用,生成随机 salt 值并在单个函数中创建哈希。将下列代码添加到 Encrypt.h: 

   inline HRESULT CompareSecret(
            const BYTE* Secret, DWORD SecretLength,
            const BYTE* Salt, DWORD SaltLength,
            const BYTE* Hash, DWORD HashLength
            )
   {
      DWORD CalculatedHashLength = HashLength;
      BYTE* CalculatedHash = new BYTE[HashLength];
      if (!CalculatedHash)
         return E_OUTOFMEMORY;

      CCryptProv Provider;
      HRESULT hr = EnsureAcquire(Provider);
      if (SUCCEEDED(hr))
      {
         hr = CreateSaltedHash( Provider,
               Secret, SecretLength,
               Salt, SaltLength,
               CalculatedHash, CalculatedHashLength);
         if (SUCCEEDED(hr))
         {
            hr = S_FALSE;
            if (CalculatedHashLength == HashLength)
            {
               if (0 == memcmp(Hash, CalculatedHash, HashLength))
                  hr = S_OK;
            }
         }
      }
      delete [] CalculatedHash;
      return hr;
   }

} // namespace VCUE
CompareSecret 接受机密、salt 和哈希。如果机密和 salt 的散列结果与传递给该函数的哈希相同,则 CompareSecret 返回 S_OK。如果哈希不同,则该函数返回 S_FALSE。否则,该函数返回错误 HRESULT。 

这些函数就是验证用户密码所需要的全部函数。HashSecret 用于从用户的密码生成将存储在数据库中的 salt 和哈希。CompareSecret 将存储的 salt 和哈希与密码进行比较并通知您它们是否匹配。 


以上是msdn里的例子,可是我按照它写了个程序,可是生成不了密码,症状是密码改变,生成的字符串不变。
求大侠们,帮帮忙,看看怎么回事,要整合,上面程序该怎么改。

#5


用sha512 应当是安全的了吧 呵呵

#6


学习啊

#1


http://www.obviex.com/samples/EncryptionWithSalt.aspx

#2


Md5算法已经被破解,不要再用它了。用SHA1吧。

#3


SHA1也不远了

#4


Visual C++ 概念:添加功能   

确保用户密码的安全
在这一步中,您将创建一些 Helper 函数以简化散列和比较密码的过程。这些代码将使用 ATL Server 提供的加密类。

为加密的 Helper 函数创建新的头文件 

在解决方案资源管理器中,右击 Tutorial 项目。 
在快捷菜单上,单击“添加”,然后单击“添加新项”。 
将出现“添加新项”对话框。 

在“模板”窗格中,单击“头文件 (.h)”,并在“名称”框中输入“Encrypt.h”。 
单击“打开”。 
Visual Studio 在磁盘上创建文件并将它添加到您的项目中。 

将下列代码添加到 Encrypt.h: 
#pragma once

#include <atlcrypt.h>

namespace VCUE
{
   inline HRESULT EnsureAcquire(
         CCryptProv& prov,
         LPCTSTR pszContainer = NULL,
         LPCTSTR pszProvider = MS_DEF_PROV,
         DWORD dwProvType = PROV_RSA_FULL,
         DWORD dwFlags = CRYPT_VERIFYCONTEXT | CRYPT_SILENT
         )
   {
      HRESULT hr = prov.Initialize(dwProvType, pszContainer, 
      pszProvider, dwFlags);

      if (hr == NTE_KEYSET_NOT_DEF)
            hr = prov.Initialize(dwProvType, pszContainer, pszProvider,
                                            dwFlags | CRYPT_NEWKEYSET);

      return hr;
   }
}
EnsureAcquire 是初始化加密提供程序(一个提供加密函数的对象)的 Helper 函数。该函数通过设置下面两个标记,提供用于服务器应用程序的灵敏默认参数:一个是禁用加密提供程序可能向用户显示的任何用户界面的标记 (CRYPT_SILENT),另一个是通知提供程序不需要访问私钥的标记 (CRYPT_VERIFYCONTEXT)。该函数还确保在初始化因容器不存在而失败时尝试创建容器。有关更多信息,请参见 CCryptProv::Initialize。将下列代码添加到 Encrypt.h: 

   inline HRESULT CreateSaltedHash(
            CCryptProv& Provider,
            const BYTE* Secret, DWORD SecretLength,
            const BYTE* Salt, DWORD SaltLength,
            BYTE* Hash,   DWORD& HashLength
         )
   {
      HRESULT hr = E_FAIL;
      HCRYPTHASH hHash = 0;
      if (CryptCreateHash(Provider.GetHandle(), CALG_MD5, 
          0, 0, &hHash))
      {
         CCryptHash oHash(hHash, TRUE);
         hr = oHash.AddData(Secret, SecretLength);
         if (SUCCEEDED(hr))
         {
            hr = oHash.AddData(Salt, SaltLength);
            if (SUCCEEDED(hr))
            {
               DWORD Size = 0;
               hr = oHash.GetSize(&Size);
               if (SUCCEEDED(hr))
               {
                  if (Size <= HashLength)
                     hr = oHash.GetValue(Hash, &HashLength);
                  else
                     hr = E_OUTOFMEMORY;
               }
            }
         }
      }

      return hr;
   }
CreateSaltedHash 使用 MD5 哈希算法从机密(如密码)和 salt(一个随机数)生成哈希。这些代码创建 CCryptHash 对象,将机密和 salt 添加到哈希,然后在调用方所提供缓冲区的大小可以容纳哈希值时获取该值。将下列代码添加到 Encrypt.h: 

   inline HRESULT HashSecret(
            const BYTE* Secret, DWORD SecretLength,
            BYTE* Salt, DWORD& SaltLength,
            BYTE* Hash, DWORD& HashLength
            )
   {
      CCryptProv Provider;
      HRESULT hr = EnsureAcquire(Provider);
      if (SUCCEEDED(hr))
      {
         hr = Provider.GenRandom(SaltLength, Salt);
         if (SUCCEEDED(hr))
         {
            hr = CreateSaltedHash( Provider,
                  Secret, SecretLength,
                  Salt, SaltLength,
                  Hash, HashLength);
         }
      }
      return hr;
   }
HashSecret 获取机密并返回 salt 以及通过合并机密和 salt 所生成的哈希。它包装获取加密提供程序所需的调用,生成随机 salt 值并在单个函数中创建哈希。将下列代码添加到 Encrypt.h: 

   inline HRESULT CompareSecret(
            const BYTE* Secret, DWORD SecretLength,
            const BYTE* Salt, DWORD SaltLength,
            const BYTE* Hash, DWORD HashLength
            )
   {
      DWORD CalculatedHashLength = HashLength;
      BYTE* CalculatedHash = new BYTE[HashLength];
      if (!CalculatedHash)
         return E_OUTOFMEMORY;

      CCryptProv Provider;
      HRESULT hr = EnsureAcquire(Provider);
      if (SUCCEEDED(hr))
      {
         hr = CreateSaltedHash( Provider,
               Secret, SecretLength,
               Salt, SaltLength,
               CalculatedHash, CalculatedHashLength);
         if (SUCCEEDED(hr))
         {
            hr = S_FALSE;
            if (CalculatedHashLength == HashLength)
            {
               if (0 == memcmp(Hash, CalculatedHash, HashLength))
                  hr = S_OK;
            }
         }
      }
      delete [] CalculatedHash;
      return hr;
   }

} // namespace VCUE
CompareSecret 接受机密、salt 和哈希。如果机密和 salt 的散列结果与传递给该函数的哈希相同,则 CompareSecret 返回 S_OK。如果哈希不同,则该函数返回 S_FALSE。否则,该函数返回错误 HRESULT。 

这些函数就是验证用户密码所需要的全部函数。HashSecret 用于从用户的密码生成将存储在数据库中的 salt 和哈希。CompareSecret 将存储的 salt 和哈希与密码进行比较并通知您它们是否匹配。 


以上是msdn里的例子,可是我按照它写了个程序,可是生成不了密码,症状是密码改变,生成的字符串不变。
求大侠们,帮帮忙,看看怎么回事,要整合,上面程序该怎么改。

#5


用sha512 应当是安全的了吧 呵呵

#6


学习啊