Hướng dẫn cách mã hóa mật khẩu và đăng nhập bằng SSHA1


SHA1 hiện nay là một trong những phương pháp mã hóa bảo mật nhất được dùng rộng rãi mặc dù chưa phải là mới nhất ( còn có SHA256, SHA384, SHA512). Tuy nhiên nó có một điểm yếu đó là một mật khẩu sẽ được mã hóa ra một đoạn string duy nhất nên nếu ai có thể tập hợp được tất cả các đoạn string đó là có thể hack được password mặc dù họ ko biết mật khẩu thật là gì (phương pháp rainbow table). Mặc dù sác suất này là rất nhỏ nhưng vẫn có thể xảy ra. Vì vậy SSHA ra đời (Salted SHA). Ý tưởng chính là mỗi lần mã hóa một đoạn salt ngẫu nhiên sẽ được gắn vào đuôi đoạn mật khẩu rồi mới mã hóa. Như vậy cùng là một mật khẩu "123456" thì mỗi lần mã hóa sẽ được một đoạn string khác nhau, khi đó rainbow table cũng chịu. Cách thực thi đơn giản với .NET Framework như sau.

    public static string GenerateSaltedSHA1(string plainTextString)
    {
      var algorithm = new SHA1Managed();
      var saltBytes = GenerateSalt(4);
      var plainTextBytes = Encoding.ASCII.GetBytes(plainTextString);

      var plainTextWithSaltBytes = AppendByteArray(plainTextBytes, saltBytes);
      var saltedSHA1Bytes = algorithm.ComputeHash(plainTextWithSaltBytes);
      var saltedSHA1WithAppendedSaltBytes = AppendByteArray(saltedSHA1Bytes, saltBytes);

      return "{SSHA}" + Convert.ToBase64String(saltedSHA1WithAppendedSaltBytes);
    }

    private static byte[] GenerateSalt(int saltSize)
    {
      var rng = new RNGCryptoServiceProvider();
      var buff = new byte[saltSize];
      rng.GetBytes(buff);
      return buff;
    }

    private static byte[] AppendByteArray(byte[] byteArray1, byte[] byteArray2)
    {
      var byteArrayResult = new byte[byteArray1.Length + byteArray2.Length];

      for (var i = 0; i < byteArray1.Length; i++) {
        byteArrayResult[i] = byteArray1[i];
      }        

      for (var i = 0; i < byteArray2.Length; i++) {
        byteArrayResult[byteArray1.Length + i] = byteArray2[i];
      }

      return byteArrayResult;
    }

Để generate ra mật khẩu chỉ cần gọi đơn giản

GenerateSaltedSHA1("123456");

Bạn sẽ lưu đoạn mã hóa này trong Database và để xác thực thì dùng hàm sau :

    public static bool AuthenticateSSHA1(string plainPassword, string hashedPassword)
    {
      byte[] buf = Convert.FromBase64String(hashedPassword.Replace("{SSHA}", string.Empty));

      var hashedWithoutSalt = new byte[buf.Length - 4];
      Array.Copy(buf,hashedWithoutSalt,buf.Length-4);           
      var saltBytes = new byte[4];
      Array.Copy(buf,buf.Length-4,saltBytes,0,4);

      var plainTextBytes = Encoding.ASCII.GetBytes(plainPassword);
      var plainTextWithSaltBytes = AppendByteArray(plainTextBytes, saltBytes);
      var algorithm = new SHA1Managed();

      if (algorithm.ComputeHash(plainTextWithSaltBytes).SequenceEqual(hashedWithoutSalt))
        return true;

      return false;
    }

Chúc thành công !

Bình luận (0)

Bình luận (<{ numberComments }>)

  • avatar
    <{ comment.author.username }> Reply
    <{ comment.createdAt | date:'yyyy-MM-dd HH:mm:ss' }>
    • avatar
      <{ reply.author.username }>
      <{ reply.createdAt | date:'yyyy-MM-dd HH:mm:ss' }>