2012-06-22 23 views
5

Bir CS büyük ve ben sadece bir ASP.net sitesi tasarımı yaptım ve site için bir giriş kimlik doğrulama sistemi gerekiyordu ... Ben gerçekten öğrenmek istediğim gibi SQLMembershipProvider kullanmak istemedim Kendi başıma nasıl yapılacağı ... Her neyse, bu benim ortaya çıktığım şey, ve bana birileri bana bir geri bildirim, ipucu veya tavsiye verebilir mi diye merak ediyordum. PeşinASP.net kimlik doğrulaması

Teşekkür

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Security.Cryptography; 

/// <summary> 
/// Summary description for PwEncrypt 
/// </summary> 
public class PwEncrypt 
{ 
    public const int DefaultSaltSize = 5; 

    private static string CreateSalt() 
    { 
     RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); 
     byte[] buffer = new byte[DefaultSaltSize]; 
     rng.GetBytes(buffer); 
     return Convert.ToBase64String(buffer); 
    } 

    public static string CreateHash(string password, out string salt) 
    { 
     salt = CreateSalt(); 
     string saltAndPassword = String.Concat(password, salt); 
     string hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPassword, "SHA1"); 
     hashedPassword = string.Concat(hashedPassword, salt); 
     return hashedPassword; 
    } 
     public static string CreateHashAndGetSalt(string password, string salt) 
    { 

     string saltAndPassword = String.Concat(password, salt); 
     string hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPassword, "SHA1"); 
     hashedPassword = string.Concat(hashedPassword, salt); 
     return hashedPassword; 
    } 

    public static bool comparePassword(string insertedPassword, string incUserName, out string newEncryptedPassword, out string originalPassword) 
    { 
     databaseInteraction DBI = new databaseInteraction(); 
     string actualPassword =""; 
     string salt = ""; 


     DBI.getSaltandPassword(incUserName, out salt, out actualPassword); 
     string hashedIncPassword = PwEncrypt.CreateHashAndGetSalt(insertedPassword, salt); 
     // hashedIncPassword = string.Concat(hashedIncPassword, salt);  
     newEncryptedPassword = hashedIncPassword; 
     originalPassword = actualPassword; 
     if (newEncryptedPassword == originalPassword) 
     { 

      return true; 
     } 

     else { return false; } 

    } 
+0

Özel üyelik sağlayıcı oluşturmak istiyorsanız, önce MemberShipProvider'dan miras almanız gerekir. Ve google biraz eğer bu oldukça iyi belgelenmiştir. –

+2

Başka hiçbir seçeneğiniz olmadıkça kendi özel kimlik doğrulama ve oturum yönetimi planlarınızı aktarmaya veya kendi kontrollerinizi oluşturmaya çalışmayın. Sadece yapmak istiyorum, uygun değil. İlginç bir okuma: http://www.troyhunt.com/2010/07/owasp-top-10-for-net-developers-part-3.html –

+0

@ChristopheGeers Tam olarak ... Kendiniz yapmak oldukça zahmetli. ÜyelikProviders iyi çalışır, jut bunu yapmak için yapılandırılmış olması gerekir. – sinni800

cevap

1

biz Sonra bir hesap nesne

private static Account GetByName(string accountName, bool activatedOnly = false) 
{ 
    using (var context = new DBEntities()) 
    { 
     return context.Accounts.FirstOrDefault(s => 
      s.AccountName == accountName && 
      s.IsApproved == activatedOnly); 
    } 
} 

public static Account Get(string accountName, string password) 
{ 
    var account = GetByName(accountName, true); 
    if (account != null) 
     if (!Cryptographer.IsValidPassword(password, 
              account.PasswordSalt, 
              account.PasswordKey)) 
      return null; 
    return account; 
} 

döndüren bazı yardımcı sınıf oluşturabilir bu

enter image description here

gibi hesaplar için bir tablo var varsayalım EntityFramework kullanıyorum ama burada önemli değil. Ana fikir, tüm hesap listesini almanıza gerek olmadığını gösterir (özellikle büyük bir kullanıcı listeniz varsa). Cource

public class Cryptographer 
{ 
    private const int keyByteLength = 20; 
    public static void Encrypt(string password, 
           out byte[] salt, 
           out byte[] key) 
    { 
     using (var deriveBytes = new Rfc2898DeriveBytes(password, 
                 keyByteLength)) 
     { 
      salt = deriveBytes.Salt; 
      key = deriveBytes.GetBytes(keyByteLength); 
     } 
    } 
    public static bool IsValidPassword(string password, 
             byte[] salt, 
             byte[] key) 
    { 
     using (var deriveBytes = new Rfc2898DeriveBytes(password, salt)) 
     { 
      byte[] newKey = deriveBytes.GetBytes(keyByteLength); 
      return newKey.SequenceEqual(key); 
     } 
    } 
} 

Kendine ait algoritması uygulayabilirsiniz gibi
Benim Cryptographer sınıf görünüyor.

+0

Teşekkürler, bu tam olarak aradığım geri bildirim türüdür ... Rfc2898DeriveBytes vs RNGCryptoServiceProvider ve FormsAuthentication.HashPasswordForStoringInConfigFile kullanarak ... İlgili daha güçlü karma algoritması var? Kullanıcıların tam listesini elde etmek için, diğer yöntemler gerçekten de kullanıcının parolayı kontrol etmesini sağlamaya çalışmaktadır, incUserID şifre kontrolünü sadece bir taneyle sınırlandırır, yani sadece 1 getiri ile tüm veritabanına karşı seçim yapar. EntityFramework aynı şeyi yapar mıydı? – user1474120

+0

@ user1474120 - Sahip olacağınız temel sorun, güvenli SQL sorguları yazmaktır. Kendi kodunuza bağlı olarak, güvenli bir şifre şeması kullanmıyorsunuz, bu da sorun ve kullanıcı ve şifreyi güvenli bir şekilde almak daha büyük bir sorundur. –

+0

@ user1474120, [bu] 'ya bir göz atın (http://security.stackexchange.com/questions/2051/is-pbkdf2-based-system-cryptology-rfc2898derivebytes-better-for-unicode-pass) – Shymep