none
请问ASPNET中membership的默认SHA1算法是怎样的? RRS feed

  • 问题

  • 为什么我用SHA1算法算出来的密码与SQL Server 数据库中的密码不一样,是我的算法有问题吗?

                Public Function EncodePassword(ByVal hashAlgorithmType As String, ByVal password As String, ByVal salt As String) As String

            Dim passwordBuf() As Byte = System.Text.Encoding.Unicode.GetBytes(password)
            Dim saltBuf() As Byte = Convert.FromBase64String(salt)

            Dim buf() As Byte = New Byte(passwordBuf.Length + saltBuf.Length) {}

            System.Buffer.BlockCopy(saltBuf, 0, buf, 0, saltBuf.Length)
            System.Buffer.BlockCopy(passwordBuf, 0, buf, saltBuf.Length, passwordBuf.Length)

            Dim hashAlgorithm As HashAlgorithm = hashAlgorithm.Create(hashAlgorithmType)
            buf = hashAlgorithm.ComputeHash(buf)
            Return Convert.ToBase64String(buf)
        End Function

    该算法算出来的密码是:3ZaOkAda+f0qxNuSRfqNjCUqy3w=

    而我数据库的存储数据是:
    密码:111111
    passwordsalt:gZvD+nDjPxgUZG6cDKjuxA==
    password:RpBNi3kU5rF9iGR2JIloAxq7aJs=
    这是为什么呢?难道Membership的默认SHA1算法不是这样的吗?

    • 已编辑 Jackzhu 2009年9月20日 14:24 写错了
    2009年9月20日 14:22

答案

  • 我终于知道原因了
    原来加密时,password和passwordsalt在组合时,应该在字符串string时就开始组合了,而不是原来我以为得先化为byte字符数组再连接。
    下面是该加密算法:
    谢谢大家的鼎力帮助!太兴奋了!

        Public Function EncodePassword(ByVal pass As String, ByVal passwordFormat As Integer, ByVal salt As String) As String
            If passwordFormat = 0 Then
                Return pass

            End If
            Dim src() As Byte = Convert.FromBase64String(salt)
            Dim inArray() As Byte = Nothing

            If (passwordFormat = 1) Then
                Dim hashAlgorithm As HashAlgorithm = hashAlgorithm.Create("SHA1")
                If ((hashAlgorithm Is Nothing)) Then
                    Throw New Exception()
                End If
                inArray = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes((Encoding.Unicode.GetString(src) & pass)))
            Else
            End If
            Return Convert.ToBase64String(inArray)

        End Function

    • 已标记为答案 Jackzhu 2009年9月22日 13:43
    2009年9月22日 13:43

全部回复

  •   public string EncodePassword(string pass, string saltBase64)
            {
                byte[] bytes = Encoding.Unicode.GetBytes(pass);
                byte[] src = Convert.FromBase64String(saltBase64);
                byte[] dst = new byte[src.Length + bytes.Length];
                Buffer.BlockCopy(src, 0, dst, 0, src.Length);
                Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
                HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
                byte[] inArray = algorithm.ComputeHash(dst);
                return Convert.ToBase64String(inArray);
            }
    2009年9月20日 14:44
  • 我的算法和你的算法其实是一样的阿,可是为什么我用这个算法加密的密码就是和数据库中存储的密码不一样呢?
    我的 ASPNET提供程序是System.Web.Security.SqlMembershipProvider,这个问题已经困扰了我一个多星期了。希望有人能给我解答,万分感谢!
    2009年9月21日 7:00
  • 这是微软产品机密 不能有漏洞 你知道方法就行了 创造你熟悉加密算法来创造你的程序加密
    2009年9月21日 8:26
  • mldark,谢谢!
    那我如果想从基于Form的应用程序访问数据库,该通过什么方式验证用户的密码呢?
    我原先是想通过上面的加密函数所得的哈希密码与数据库中的密码对比,现在,我不清楚该怎么核对用户输入的密码了。

    2009年9月21日 10:59
  • mldark,谢谢!
    那我如果想从基于Form的应用程序访问数据库,该通过什么方式验证用户的密码呢?
    我原先是想通过上面的加密函数所得的哈希密码与数据库中的密码对比,现在,我不清楚该怎么核对用户输入的密码了。


    这个需求 由你自己选择 那上面方法可以现实的  输入密码进入加密同样的方式  然后从数据库读取加密数据 都转换byte数组  两个数组每个项核对一下 有一个不核对的话 返回false
    2009年9月21日 14:07
  • 如果我没有记错 是 machine code 不同?


    恭喜自己5星用户达成
    2009年9月21日 14:13
  • 为什么我用这个计算得到的数据是正确的?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    namespace ConsoleApplication12
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.Write(EncodePassword("11111",1,"+5ckXA1F1JiNEjQCk2BVWQ=="));
    
                    Console.ReadKey ();
    
            }
    
    
          static   internal string EncodePassword(string pass, int passwordFormat, string salt)
            {
                if (passwordFormat == 0)
                {
                    return pass;
                }
                byte[] bytes = Encoding.Unicode.GetBytes(pass);
                byte[] src = Convert.FromBase64String(salt);
                byte[] dst = new byte[src.Length + bytes.Length];
                byte[] inArray = null;
                Buffer.BlockCopy(src, 0, dst, 0, src.Length);
                Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
                if (passwordFormat == 1)
                {
                    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
                    if ((algorithm == null) )
                    {
                        throw new Exception();
                    }
                    inArray = algorithm.ComputeHash(dst);
                }
                else
                {
                   
                }
                return Convert.ToBase64String(inArray);
            }
    
     
    
     
    
        }
    
    }
    

    恭喜自己5星用户达成
    2009年9月21日 15:22
  •  楼上你的数据是什么结果?
    2009年9月21日 15:39
  • 现在是我已经有了用ASP.NET成员资格管理的用户数据库,总不能为了编一个基于C/S结构的程序就把先前的用户全部否定掉吧!请问微软有没有提供给基于Form的程序一个类似MembershipProvider的类阿?

    2009年9月22日 1:00
  • 谢谢韦恩卑鄙
    如果我没有记错 是 machine code 不同?

    我并没有设置machine,所以,应该不是这个

    2009年9月22日 1:02
  • 确实不是machine code的问题

    但是用我贴出来的代码 结果和数据库一样啊

    pwd
    12345

    salt
    +5ckXA1F1JiNEjQCk2BVWQ==
     
    resualt
    9o4yzy1apfPYwbSw/VKSuTDwH/k=



    pwd
    123456

    salt
    nH8F3pqVqtrerjNeAiYYKA==

    resualt
    GLJQ6/ndqdPvDpXdLwAFjlFw/UA=


    全都正确啊


    恭喜自己5星用户达成
    2009年9月22日 1:15
  • 楼主你好,

    韦恩的的确是对的。我已经测试过了,与machine code 无关。如果你仍然有问题,你可以把你的密码和salt参数贴出来我们帮你测试下。


    Microsoft Online Community Support
    2009年9月22日 3:18
  • 原来这样的啊 

    我想问的salt是怎么生成来的

    2009年9月22日 3:55
  • salt是算法自动生成的一个随机数。
    Microsoft Online Community Support
    2009年9月22日 3:57
  • 现在是我已经有了用ASP.NET成员资格管理的用户数据库,总不能为了编一个基于C/S结构的程序就把先前的用户全部否定掉吧!请问微软有没有提供给基于Form的程序一个类似MembershipProvider的类阿?


    你可以继承MembershipProvider扩展需求 没有类似的 微软已经都写好基本功能方法的 membership
    2009年9月22日 4:05
  • salt 直接从数据库里面读 passwordSalt
    恭喜自己5星用户达成
    2009年9月22日 4:11
  •     Public Function EncodePassword(ByVal pass As String, ByVal passwordFormat As Integer, ByVal salt As String) As String
            If passwordFormat = 0 Then
                Return pass

            End If
            Dim bytes() As Byte = Encoding.Unicode.GetBytes(pass)
            Dim src() As Byte = Convert.FromBase64String(salt)
            Dim dst() As Byte = New Byte(src.Length + bytes.Length) {}
            Dim inArray() As Byte = Nothing
            System.Buffer.BlockCopy(src, 0, dst, 0, src.Length)
            System.Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length)
            If (passwordFormat = 1) Then
                Dim hashAlgorithm As HashAlgorithm = hashAlgorithm.Create("SHA1")
                If ((hashAlgorithm Is Nothing)) Then
                    Throw New Exception()
                End If
                inArray = hashAlgorithm.ComputeHash(dst)
            Else
            End If
            Return Convert.ToBase64String(inArray)

        End Function


    我的算法,我的测试是这样的
    pwd
    12345

    salt
    +5ckXA1F1JiNEjQCk2BVWQ== 

    resualt
    kaVrUabOdCbig41WntjAnh1+9eE=



    pwd
    123456

    salt
    nH8F3pqVqtrerjNeAiYYKA==

    resualt
    psvbUPnujDUSLtW1P7JFOGM+Gh0=

    奇了怪了

    2009年9月22日 11:32
  • password                                                                   passwordformat                passwordsalt

    u/SzRDK/f0yYQKl3N+Zsp4jKdAk=         1        nrFpCbjto1Df/2gjaLccIQ==
    2R24hmNGvFYb5MMZDEfLAey8Xjw=         1        SrIKBmCqyo9ATB5SSMRrfQ==
    JcFFqQUU1YttoZyXmKwnw/gmwjs=         1        UlQiym0+3NTybZ801MPUsw==


    以上是我数据库中的数据,密码都是:123456
    可我通过

        Public Function EncodePassword(ByVal pass As String, ByVal passwordFormat As Integer, ByVal salt As String) As String
            If passwordFormat = 0 Then
                Return pass

            End If
            Dim bytes() As Byte = Encoding.Unicode.GetBytes(pass)
            Dim src() As Byte = Convert.FromBase64String(salt)
            Dim dst() As Byte = New Byte(src.Length + bytes.Length) {}
            Dim inArray() As Byte = Nothing
            System.Buffer.BlockCopy(src, 0, dst, 0, src.Length)
            System.Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length)
            If (passwordFormat = 1) Then
                Dim hashAlgorithm As HashAlgorithm = hashAlgorithm.Create("SHA1")
                If ((hashAlgorithm Is Nothing)) Then
                    Throw New Exception()
                End If
                inArray = hashAlgorithm.ComputeHash(dst)
            Else
            End If
            Return Convert.ToBase64String(inArray)

        End Function
    该算法算出来的结果是:
    bR77+Rsin07so5oaJxw4FWVOTsM=                 nrFpCbjto1Df/2gjaLccIQ==
    kJAnthcV0qQdNSFAGyyjuSOt1rw=                  SrIKBmCqyo9ATB5SSMRrfQ==
    DL7UCwTPJN68SDcBbBMkPu8vfWw=             UlQiym0+3NTybZ801MPUsw==

    2009年9月22日 11:48
  • 我终于知道原因了
    原来加密时,password和passwordsalt在组合时,应该在字符串string时就开始组合了,而不是原来我以为得先化为byte字符数组再连接。
    下面是该加密算法:
    谢谢大家的鼎力帮助!太兴奋了!

        Public Function EncodePassword(ByVal pass As String, ByVal passwordFormat As Integer, ByVal salt As String) As String
            If passwordFormat = 0 Then
                Return pass

            End If
            Dim src() As Byte = Convert.FromBase64String(salt)
            Dim inArray() As Byte = Nothing

            If (passwordFormat = 1) Then
                Dim hashAlgorithm As HashAlgorithm = hashAlgorithm.Create("SHA1")
                If ((hashAlgorithm Is Nothing)) Then
                    Throw New Exception()
                End If
                inArray = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes((Encoding.Unicode.GetString(src) & pass)))
            Else
            End If
            Return Convert.ToBase64String(inArray)

        End Function

    • 已标记为答案 Jackzhu 2009年9月22日 13:43
    2009年9月22日 13:43