日程项目中的一些安全策略

在本人的日程管理项目中,既然涉及到了用户登录这一功能,并且是一个联网系统,那么安全策略是必不可少的,以下是本项目的一些安全策略实现:

1.MySQL数据存储加密

        用户信息的安全始终是第一位的,数据库加密则是必不可少的一环。

具体策略如下:

        ·用户密码采用SHA1不可逆加密算法

        ·用户邮箱采用CBC对称加密算法

效果如下(摘自用户信息存储数据表):
| uid | username | password                                 | email                                                              | created_at          |
+-----+----------+------------------------------------------+--------------------------------------------------------------------+---------------------+
|   2 | test     | af048c5e9f7684536de4544114a8e3292cde1740 | 0fafbc2ad0d54bc2ae0b27ecd4b2a7a2ccb67bff337be525cac0538f5a1741d474 | 2023-04-13 23:18:12 |
|   3 | test1    | af048c5e9f7684536de4544114a8e3292cde1740 | ff47471240fc0adfeacd6f656f49b7b3                                   | 2023-05-22 13:07:25 |

        SHA1算法相对MD5等算法增加了破解成本,提高了安全性

        CBC算法因其需要密钥,偏移量两个变量进行加密,也降低了在无法使用不可逆加密算法时的风险程度(因加密,解密均由服务器后端完成,故认为无需使用非对称加密)

实现方式如下(因此博客公开,故不展示CBC密钥及偏移量): 
//CBC加密
public String cbc(String str){
        String key="KEY HERE";
        String iv="IV HERE";
        if(str==null) return "";
        CBC cbc=new CBC(key,iv);
        cbc.setPlaintext(str);
        cbc.Encrypt();
        return cbc.showCiphertext();
    }
//SHA1加密
public String sha1(String str) throws NoSuchAlgorithmException {
        if(str==null) return "";
        MessageDigest sha128=MessageDigest.getInstance("SHA-1");
        sha128.update(str.getBytes());
        byte[] res=sha128.digest();
        StringBuilder sb = new StringBuilder();
        for(byte bite : res) {
            sb.append(String.format("%02x", bite));
        }
        return sb.toString();

    }
//具体实现
info.password=encrypt.sha1(encrypt.cbc(info.password));
info.email=encrypt.cbc(info.email);

2.登录态验证

        登录态验证是避免水平越权的重要途径,在本项目中的实现方式主要有:对未登录用户禁止访问部分接口,限定数据库查询语句仅可查询当前登录态用户的数据。当前登录用户采用uid作为唯一标识符。

实现方式如下:
服务器验证:
//验证登录态
@SaCheckLogin
//获取登录态
int uid = Integer.parseInt(StpUtil.getLoginId().toString());

        仅是一行注解和代码的内容,这便是SaToken框架的简便之处

数据库验证:
select * from schedule where owner=#{uid} order by end_at DESC;

        通过验证数据表中的owner字段来保证用户只能操作自己的内容

3.恶意请求过滤及服务器异常捕获

        恶意请求是服务器运行的一大阻碍,可能造成服务器崩溃,数据泄露等安全问题。SpringBoot框架,MyBatis框架以及SaToken框架因其相对成熟,已经从框架层面避免了部分因恶意请求造成的漏洞,包括但不限于:

        · SQL注入攻击

        · 恶意cookie

        · 不符合类型要求的URL参数

但是仍有部分恶意请求需要手动过滤,包括但不限于:

        · 超长字符串

        · 不合规的数字

其中,对于部分异常可以通过忽略或返回请求空体或者直接返回400/500状态码解决

其余的过滤方式如下:
//摘自新建日程处理部分
if(info.begin>info.end||info.event.length()>500||info.tag.length()>120)
            throw new InvalidRequest();//超长字符串和非法起止时间的过滤
if(info.repeat<0||info.repeat>3650) info.repeat=0;//非法重复周期和超长重复周期的过滤
if(end_n<0||end>rt.size()) end_n=rt.size();
if(begin_n<0) begin_n=0;
//不合法的切片数据过滤

部分非法数据可以通过将其限制在合法范围内解决,剩余的交给异常捕获器处理。

异常捕获器避免了报错信息的直接反馈,同时避免了服务器崩溃,也能告知用户出现的问题

实现方式如下:
 //运行时错误捕获并输出至日志
@ExceptionHandler
    public Response globalFilter(Throwable e, HttpServletResponse res){
        res.setStatus(500);
        logger.error("Runtime error found at "+dateToStamp.stampToDate(System.currentTimeMillis())+
                "with exception"+e.toString());
        return new Response(ReturnCode.UnknownError);
    }
//处理请求异常捕获并输出到日志
@ExceptionHandler
public Response filter(ResponseError e, HttpServletResponse res){
        res.setStatus(e.status);
        logger.warn("Server exception found at"+dateToStamp.stampToDate(System.currentTimeMillis())+"with code"+e.status);
        return new Response(e.info);
}
@ExceptionHandler
public Response NoLogin(NotLoginException e,HttpServletResponse res){
        res.setStatus(401);
        return new Response(ReturnCode.NoPrivileges);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值