注册和登录还有那个加密的密码
假设你在设计自己的系统的时候采用的是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层中的方法,那么这些客户端都需要先将密码进行加密,然后调用服务。
现在需要增加php客户端,android 客户端。于是变成了:
所以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);
}
}