六大质量属性—安全性代码层面描述(以“信息领域热词分析系统”为例)

 

 

   安全性是六大质量属性中及其重要的,往往被开发者忽略;但如果忽略了安全性出现安全问题却是难以挽救的。

  (一)安全性战术的目标是:

    1,检测网络攻击;

    2,抵抗网络攻击;

    3,很快的从攻击中恢复。

  (二)常见的安全攻击有:

1,XSS攻击:即跨站点脚本攻击,指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。分类:反射型和持久型

    解决方式:1,消毒(将特殊字符转义)2,禁止访问带有HttpOnly的敏感Cookie数据,

  2,注入攻击:如SQL注入,OS注入

  解决方式:1,消毒(通过正则表达式过滤可能的恶意SQL命令)2,参数绑定

  3,CSRF攻击:跨站点请求伪造,伪造用户请求

  解决方式:1,添加表单Token(标记)2,验证码3,Referer check

  4,Error Code:错误回显,通过系统报错的信息寻找漏洞

  解决方式:通过配置web服务器参数跳转500专门错误页面

  5,HTML注释:

  6,文件上传:通过上传可执行程序进行攻击。

  解决方式:限制上传文件类型

  7,路径遍历

(三)提起安全性就不得不提数据加密的问题,常见的数据加密:

  1. 单项散列加密:将要加密的信息进行散列计算得到固定长度的输出信息。为了安全性,可以给散列算法添加密匙(salt)增加破解难度。常见的相应算法:MD5,SHA。只能将明文转为密文;不能将密文转为明文。
  2. 对称加密:加密和解密使用同一个密匙(或互相推算);优点:算法简单,加解密效率高,系统开销小,适合对大量数据加密;缺点:使用同一个密匙,远程通信下难以安全的交换。常用算法:DES,RC
  3. 非对称加密:加密和解密使用不同的密匙;公匙对外公开,私匙只有所有者知道;使用公匙加密,则使用私匙解密;使用私匙加密,则使用公匙解密。常用算法:RSA,HTTPS传输使用的数字证书就是非对称加密的公匙。

      (四)安全性常用战术:

       

 

   (五)安全性在信息热词系统中的使用:

    1,首先用户注册登录的账号和密码要进行信息加密;避免不法用户破解密码;(3DES加密)

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypDES3 {

    // KeyGenerator 提供对称密钥生成器的功能,支持各种算法
    private KeyGenerator keygen;
    // SecretKey 负责保存对称密钥
    private SecretKey deskey;
    // Cipher负责完成加密或解密工作
    private Cipher c;
    // 该字节数组负责保存加密的结果
    private byte[] cipherByte;

    public EncrypDES3() throws NoSuchAlgorithmException, NoSuchPaddingException {
        // 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
        keygen = KeyGenerator.getInstance("DESede");
        // 生成密钥
        deskey = keygen.generateKey();
        // 生成Cipher对象,指定其支持的DES算法
        c = Cipher.getInstance("DESede");
    }

    /**
     * 对字符串加密
     */
    public byte[] Encrytor(String str) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
        c.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] src = str.getBytes();
        // 加密,结果保存进cipherByte
        cipherByte = c.doFinal(src);
        return cipherByte;
    }

    /**
     * 对字符串解密
     */
    public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
        c.init(Cipher.DECRYPT_MODE, deskey);
        cipherByte = c.doFinal(buff);
        return cipherByte;
    }

    /**
     * 主函数
     */
    public static void main(String[] args) throws Exception {
        EncrypDES3 des = new EncrypDES3();
        String msg ="You are not alone.";
        byte[] encontent = des.Encrytor(msg);
        byte[] decontent = des.Decryptor(encontent);
        System.out.println("明文是:" + msg);
        System.out.println("加密后:" + new String(encontent));
        System.out.println("解密后:" + new String(decontent));

    }

}

    2,其次在用户输入账号和密码时添加输入验证码,防止暴力破解,以及需要查询词条等所有输入框禁止用户输入非法字符。从而避免SQL注入问题;

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<base href="/Mvcpro/"/>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
</head>
    <body>
     <span>${msg}</span>
       <form action="emp/login" method="POST">
       <fieldset>
       <legend>请登录!</legend>
                   用户名:<input type="text" name="username" placehodler="输入用户名"><br><br>&nbsp;&nbsp;&nbsp;码: <input type="password" name="pwd" placehodler="输入密码"><br><br>
       <img alt="图片不存在" src="imgCode" height="40px"><a href="javascript:void">&nbsp;&nbsp;&nbsp;看不清,换一张!</a><br><br>
       验证码:<input type="text" name="code">
       <br><br>
       <input type="submit" value="提交">
       <input type="reset" value="重置">
        </fieldset>
       </form>
       <script type="text/javascript">
       $(function(){
       $("form a").click(function(){//为a标签绑定了一个单机事件
           $("form img").attr("src","imgCode?ran="+new Date().getTime());
       })
       })
       </script>
    </body>
</html>


package com.sxt.mvcpro.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/imgCode")
public class RandomCode extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static int WIDTH = 102;//定义验证图片的宽度
    private static int HEIGHT = 50;//定义验证图片的高度
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        response.setContentType("image/jpeg");
        ServletOutputStream sos = response.getOutputStream();
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
                BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        char[] rands = generateCheckCode();
        drawBackground(g);
        drawRands(g, rands);
        g.dispose();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(image, "JPEG", bos);
        byte[] buf = bos.toByteArray();
        response.setContentLength(buf.length);
        sos.write(buf);  //锟斤拷锟斤拷锟缴碉拷锟斤拷证锟斤拷图片写锟斤拷页锟斤拷
        bos.close();
        sos.close();
        //锟斤拷锟斤拷锟缴碉拷锟斤拷证锟诫保锟芥到session
        session.setAttribute("rand", new String(rands));
    }
    private void drawBackground(Graphics g) {
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        for (int i = 0; i < 120; i++) {
            int x = (int) (Math.random() * WIDTH);
            int y = (int) (Math.random() * HEIGHT);
            int red = (int) (Math.random() * 255);
            int green = (int) (Math.random() * 255);
            int blue = (int) (Math.random() * 255);
            g.setColor(new Color(red, green, blue));
            g.drawOval(x, y, 1, 0);
        }
    }

    private void drawRands(Graphics g, char[] rands) {
        // g.setColor(Color.BLUE);
        Random random = new Random();
        int red = random.nextInt(110);
        int green = random.nextInt(50);
        int blue = random.nextInt(50);
        g.setColor(new Color(red, green, blue));
        g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 30));
        g.drawString("" + rands[0], 5, 35);
        g.drawString("" + rands[1], 25, 34);
        g.drawString("" + rands[2], 45, 36);
        g.drawString("" + rands[3], 65, 33);
    }

    private char[] generateCheckCode() {
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] rands = new char[4];
        for (int i = 0; i < 4; i++) {
            int rand = (int) (Math.random() * 36);
            rands[i] = chars.charAt(rand);
        }
        return rands;
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

    3,在代码中多使用try...catch...,如果出现问题则抛异常;在前端页面显示时,如果出现问题统一跳转到一个报错页面;

package com.lq.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.lq.bean.CiTiao;

public class QueryFromMySql 
{
    private static String DriverName="com.mysql.jdbc.Driver";
    private static String UName="root";
    private static String Upwd="root";
    private static String Url="jdbc:mysql://192.168.25.1:3306/xinjian?useUnicode=true&characterEncoding=UTF-8";
     public int query()   //查询词条总数
        {
            Connection conn=null;
            PreparedStatement pstmt=null;
            ResultSet result=null;
            int count=-1;
            try {
                Class.forName(DriverName);
                conn=DriverManager.getConnection(Url, UName, Upwd);
                String sql="select count(*) from citiao";
                pstmt= conn.prepareStatement(sql);
                result=pstmt.executeQuery(sql);
                result.next();
                count=result.getInt(1);
                    return count;
            }
            catch(ClassNotFoundException e)
            {
                e.printStackTrace();
                return count;
            }
            catch (SQLException e)
            {
                e.printStackTrace();
                return count;
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return count;
            }
            finally {
                try {
                    if(result!=null) result.close();
                    if(pstmt!=null) pstmt.close();
                    if(conn!=null) conn.close();
                }
                catch(SQLException e)
                {
                    e.printStackTrace();
                }
            }
            
        }
     public List<CiTiao> SearchList()  //查询所有的词条信息
      {
          List<CiTiao> CiTiaos=new ArrayList<CiTiao>();
          CiTiao CiTiao=null;
          Connection conn=null;
          PreparedStatement pstmt=null;
          ResultSet result=null;
          try {
              Class.forName(DriverName);
              conn=DriverManager.getConnection(Url, UName, Upwd);
              String sql="select * from citiao limit 0,50 ";
              pstmt= conn.prepareStatement(sql);
              result=pstmt.executeQuery();
                  while(result.next())
                  {
                       int id=result.getInt("id");    //词条编号1
                       String name=result.getString("name");  //词条名称2
                       String des=result.getString("des");  //词条简单内容3
                       String url=result.getString("url");  //词条链接4
                       
                     CiTiao=new CiTiao(id,name,des,url);
                     CiTiaos.add(CiTiao);
                  }
              return CiTiaos;
          }
          catch(ClassNotFoundException e)
          {
              e.printStackTrace();
              return null;
          } 
          catch (SQLException e) 
          {
            e.printStackTrace();
            return null;
        }
          catch(Exception e)
          {
              e.printStackTrace();
              return null;
          }
          finally {
              try {
                  if(result!=null) result.close();
                  if(pstmt!=null) pstmt.close();
                  if(conn!=null) conn.close();
              }
              catch(SQLException e)
              {
                  e.printStackTrace();
              }
          }
      }
     
     public List<CiTiao> SearchByName(String name)  //根据名称查询所有的词条信息
      {
          List<CiTiao> CiTiaos=new ArrayList<CiTiao>();
          CiTiao CiTiao=null;
          Connection conn=null;
          PreparedStatement pstmt=null;
          ResultSet result=null;
          try {
              Class.forName(DriverName);
              conn=DriverManager.getConnection(Url, UName, Upwd);
              String sql="select * from citiao where name like ?";
              pstmt= conn.prepareStatement(sql);
              pstmt.setString(1,"%"+name+"%");
              result=pstmt.executeQuery();
                  while(result.next())
                  {
                      name=result.getString("name");  //词条名称2
                       String des=result.getString("des");  //词条简单内容3
                       String url=result.getString("url");  //词条链接4
                       
                     CiTiao=new CiTiao(name,des,url);
                     CiTiaos.add(CiTiao);
                  }
              return CiTiaos;
          }
          catch(ClassNotFoundException e)
          {
              e.printStackTrace();
              return null;
          } 
          catch (SQLException e) 
          {
            e.printStackTrace();
            return null;
        }
          catch(Exception e)
          {
              e.printStackTrace();
              return null;
          }
          finally {
              try {
                  if(result!=null) result.close();
                  if(pstmt!=null) pstmt.close();
                  if(conn!=null) conn.close();
              }
              catch(SQLException e)
              {
                  e.printStackTrace();
              }
          }
      }
     
     public List<CiTiao> SearchByDes(String des)  //根据分类查询所有的词条信息
      {
          List<CiTiao> CiTiaos=new ArrayList<CiTiao>();
          CiTiao CiTiao=null;
          Connection conn=null;
          PreparedStatement pstmt=null;
          ResultSet result=null;
          try {
              Class.forName(DriverName);
              conn=DriverManager.getConnection(Url, UName, Upwd);
              String sql="select * from citiao where des like ?";
              pstmt= conn.prepareStatement(sql);
              pstmt.setString(1,"%"+des+"%");
              result=pstmt.executeQuery();
                  while(result.next())
                  {
                       String name=result.getString("name");  //词条名称2
                       des=result.getString("des");  //词条简单内容3
                       String url=result.getString("url");  //词条链接4
                       
                     CiTiao=new CiTiao(name,des,url);
                     CiTiaos.add(CiTiao);
                  }
              return CiTiaos;
          }
          catch(ClassNotFoundException e)
          {
              e.printStackTrace();
              return null;
          } 
          catch (SQLException e) 
          {
            e.printStackTrace();
            return null;
        }
          catch(Exception e)
          {
              e.printStackTrace();
              return null;
          }
          finally {
              try {
                  if(result!=null) result.close();
                  if(pstmt!=null) pstmt.close();
                  if(conn!=null) conn.close();
              }
              catch(SQLException e)
              {
                  e.printStackTrace();
              }
          }
      }
     

     public static void main(String[] args) {
        QueryFromMySql queryFromMySql=new QueryFromMySql();
        //queryFromMySql.QueryBySend_time();
    }

}

    4,如果用户不进行注册直接访问某个中间网页时,则提示登录;

    5,页面与页面之间跳转的Cookie中有隐蔽信息的设置为HttpOnly属性避免XSS攻击;

response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")

    等等

posted on 2020-03-01 20:15  不愧下学  阅读(362)  评论(0编辑  收藏  举报

导航