注冊和登錄還有那個加密的密碼


假設你在設計自己的系統的時候采用的是MVC架構。例如

 

也許可能有很多童鞋會這樣設計Service和Model.

service:

public class AccountService
{
    public bool Login(string userName, string password)
    {
        // insert into account values(userName,password);
        return true;
    }

    public bool Register(string userName, string password)
    {
        // select count(*) from account where userName = userName and password = password;
        return true;       
    }
}

然后model是這樣的:

public class UserModel
{
    public bool Login(string userName, string password)
    {
        string encryptedPassword = password.MD5();

        AccountService accountService = new AccountService();
        return accountService.Login(userName, encryptedPassword);
    }

    public bool Register(string userName, string password)
    {
        string encryptedPassword = password.MD5();

        AccountService accountService = new AccountService();
        return accountService.Register(userName, encryptedPassword);       
    }
}

 

很明顯,這段代碼完成了注冊和登錄的任務,並且密碼也是以加密的形式保存的。

比如123456 =>e10adc3949ba59abbe56e057f20f883e

 

當然有些人會認為密碼不夠安全,然后進行兩次md5,或者是加salt,加userName,等。

 

下面拋一個問題:聰明的你認為上面的這種設計安全嗎???

 

 

如果你認為上面的代碼很安全,那么你就很需要往下面看看了。

Service和Model這樣設計的缺點:

1:加密在model層中做,如果你有多個界面的話,我指的是客戶端(asp.net,android,php…).然后這些客戶端調用的是service層中的方法,那么這些客戶端都需要先將密碼進行加密,然后調用服務。

image

現在需要增加php客戶端,android 客戶端。於是變成了:

image

所以asp.net Model, php Model, android Model 都需要進行相同的加密,並且你需要保證這三個平台所加密的字符串是相同的,

比如123456 =>在這三個Model層中都必須被加密為:e10adc3949ba59abbe56e057f20f883e

這是一個很惡心的問題,不過幸運的是這三個平台的md5 加密出來的是一樣的,如果不一樣的話,可能是需要設置下字符編碼。

 

2:上面的這個缺點雖然比較嚴重,但還不是最致命的,這個設計最致命的地方在於Service層沒有進行加密驗證,如果你獲取了用戶的用戶名和密碼的話,直接登錄就OK了。

 

假設A用戶的用戶名為LoveJenny,密碼為123456.

在數據庫中儲存的值是LoveJenny,e10adc3949ba59abbe56e057f20f883e。

對於hacker而言,他偶然獲取了用戶名:LoveJenny,密碼:e10adc3949ba59abbe56e057f20f883e

 

首先他嘗試試用LoveJenny 和e10adc3949ba59abbe56e057f20f883e 來調用Service服務登錄系統,f**k,Service 沒有驗證,於是他便登錄了,他不需要知道LoveJenny的密碼是123456,同時也不需要理解e10adc3949ba59abbe56e057f20f883e 是怎樣生成的,他只需要輸入用戶名:LoveJenny,然后密碼:e10adc3949ba59abbe56e057f20f883e 來調用服務就可以登錄了。

 

最后如果你還是認為:

1:他是怎樣偶然得到LoveJenny和e10adc3949ba59abbe56e057f20f883e 的?

這點我無法回答,因為我也不知道hacker會怎樣獲取,不過可以肯定的是,只要你的系統不是很安全的話,應該是可以獲取的。

2:多個model中做驗證沒什么大不了的?

這點我持反對意見,首先它違反了don’t repeat your self 原則,其次,把本該服務層中做的事情放到

model層來做,最后假設你的系統有多個平台的話,很郁悶的哦。

3:就算知道用戶名和數據庫密碼,他又怎樣繞過model來調用服務呢?

這個。。。,我還是不知道,不過萬一你的服務是暴露在外網上的,如果你老板想讓你做個開放平台,如果你的服務器被hacker掉了。。。,當然如果很多很多。。,借口

 

 

不要認為安全是個組件,到時候拿過來用就行了,個人認為在開發和設計的時候,就應該考慮安全,當然絕對的安全是不可能的,我們只能保證我們該做的都做了,而不是把這些安全漏洞歸咎於上面的幾點,或者是更多點。

最后的最后我貼上我認為正確的設計:

 

Service層:

public class AccountService
{
    public bool Login(string userName, string password)
    {
        string encryptedPassword = getEncryptedString(password);

        // insert into account values(userName,encryptedPassword);
        return true;
    }

    public bool Register(string userName, string password)
    {
        string encryptedPassword = getEncryptedString(password);

        // select count(*) from account where userName = userName and password = encryptedPassword;
        return true;       
    }
}

 

Model層:

public class UserModel
{
    public bool Login(string userName, string password)
    {
        AccountService accountService = new AccountService();
        return accountService.Login(userName, password);
    }

    public bool Register(string userName, string password)
    {
        AccountService accountService = new AccountService();
        return accountService.Register(userName, password);       
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM