5

私は CS 専攻で、ASP.net サイトの設計を終えたばかりで、そのサイトにはログイン認証システムが必要でした...自分で作成する方法を本当に学びたかったので、SQLMembershipProvider を使用したくありませんでした。 ...とにかく、これは私が思いついたものであり、誰かが私にフィードバック、ヒント、またはアドバイスをくれるかどうか疑問に思っていました.

前もって感謝します

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; }

    }
4

1 に答える 1

1

このようなアカウントのテーブルがあるとします

ここに画像の説明を入力

次に、アカウント オブジェクトを返すヘルパー クラスを作成できます。

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;
}

使用してEntityFrameworkいますが、ここでは重要ではありません。主なアイデアは、アカウントのリスト全体を取得する必要がないことを示すことです (特に、ユーザーのリストが大きい場合)。
Cryptographerのクラスは次のようになります

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);
        }
    }
}

もちろん、独自のアルゴリズムを実装することもできます。

于 2012-06-22T08:07:38.807 に答える