web安全编码Demo

 目录:

1、生成安全随机数

2、密码安全存储

3、文件上传

4、SQL注入

5、HMAC-SHA256

一、生成安全随机数

用于生成会话sessionid、防CSRF时的token、以及其他场景下的veritycode。

如下代码:生成安全随机数

package net.xdclass.demo;
import java.security.SecureRandom;

/**
 * 使用安全随机数生成器生成24byte的随机数
 */

public class OtherTest {
    public static StringBuilder createToken(){
        SecureRandom random = new SecureRandom();
        byte bytes[] =  new byte[24];
        random.nextBytes(bytes);
        StringBuilder  token = new StringBuilder();
        String hv;
        for (int i=0;i<bytes.length;i++){
            int j = bytes[i] & 0xFF;
            hv = Integer.toHexString(j);
            if (hv.length()==1){
                hv = "0"+hv;
            }
            token.append(hv);
        }
        return token;
    }

    public static  void  main(String[] args){
        System.out.println(createToken());
        System.out.println(createToken().length());

    }
}

二、密码安全存储

  • 禁止使用MD5、SHA1不安全哈希算法
  • 可以使用SHA256+salt,salt随机生成,salt长度不低于8byte,每个用户的salt不一样,salt存数据库
  • 强烈建议使用PBKDF2秘钥推到函数,安全存储用户密码

如下代码:PBKDF2存储密码DEMO

package net.xdclass.demo;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.sql.Array;

/**
 * 使用PBKDF2生成不可逆的密码
 * DK = PBKDF2(PRF, Password, Salt, c, dkLen)
 * * PRF是一个伪随机函数,例如HASH_HMAC函数,它会输出长度为hLen的结果。
 * * Password是用来生成密钥的原文密码。
 * * Salt是一个加密用的盐值。
 * * c是进行重复计算的次数。
 * * dkLen是期望得到的密钥的长度。
 * * DK是最后产生的密钥。
 */

public class OtherTest {
    public static StringBuilder savePassword(String password)throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecureRandom random = new SecureRandom();
        byte salt[] =  new byte[24];
        random.nextBytes(salt);
        int iterCount=5000;//迭代次数不低于5000次
        char[] charPassword = password.toCharArray();
        PBEKeySpec pbeKeySpec = new PBEKeySpec(charPassword,salt,iterCount,256);
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        byte[] hashpassword = secretKeyFactory.generateSecret(pbeKeySpec).getEncoded();
        StringBuilder  finalPassword = new StringBuilder();
        String hv;
        for (int i=0;i<hashpassword.length;i++){
            int j = hashpassword[i] & 0xFF;
            hv = Integer.toHexString(j);
            if (hv.length()==1){
                hv = "0"+hv;
            }
            finalPassword.append(hv);
            }
        return finalPassword;
    }
    public static  void  main(String[] args) throws NoSuchAlgorithmException,InvalidKeySpecException {
        System.out.println(savePassword("123456"));
    }
}

三、文件上传

  • 服务端通过白名单限制上传的文件类型
  • 限制文件的大小
  • 限制文件保存的目录,禁止执行权限
  • 压缩包需要考虑解压后大小、文件名是否包含目录跳转字符
  • 对上传的文件重命名,上传的路径禁止返回客户端

如下代码:获取文件类型,并判断文件名是否包含空格DEMO

package net.xdclass.demo;
import java.io.File;

/**
 * 获取上传文件的文件类型,并判断文件名是否包含空
 */

public class OtherTest {
    public static  void  main(String[] args) {
        //取上传文件的文件名
        String path="D:\MyDocument\3-java\2-Code\demo.java";
        File file  = new File(path);
        String fileName = file.getName();
        StringBuilder finalFileName = new StringBuilder();
        //去除文件名中的空字符
        for (int i=0;i<fileName.length();i++){
            if ('u0000' != fileName.charAt(i)){
                finalFileName.append(fileName.charAt(i));
            }
        }
        int i = finalFileName.lastIndexOf(".");
        String fileExtension = finalFileName.substring(i+1);
        System.out.println(fileExtension);
    }
}

四、SQL注入

防范SQL注入的方法:

  • 预编译
  • 对不可信的数据进行处理
  • 对不可信的数据进行编码

如下代码:通过预编译的方式防范SQL注入漏洞

1、错误示例,拼接SQL语句,导致存在SQL注入漏洞

package Eleven;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.*;

public class OtherTest {
    public static void main(String[] args)  throws  ClassNotFoundException, SQLException  {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user_info?serverTimezone=UTC", "root", "123456");
        Statement stmt = null;
        ResultSet rsSet = null;

        String userName = "Eleven' or '1'='1'-- ";  //拼接一个用户名,形成万能查询
        String userPassword = "123456";
        String sqlString = "select * from user where name = '" + userName +"' AND password = '" + userPassword + "'"; // 变量未经处理直接与SQL语句拼接在一起
        stmt = conn.createStatement();
        rsSet = stmt.executeQuery(sqlString);
        while(rsSet.next()) {
            String name = rsSet.getString("name");
            String password = rsSet.getString("password");
            System.out.println(name+" "+password);  //输出结果为数据库所有的用户名密码。
        }
    }
}

2、正确示例

package Eleven;
import java.sql.*;

public class Test {
    public static void main(String[] args) throws  ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user_info?serverTimezone=UTC", "root", "123456");
        String userName="Eleven";
        String userPwd="123456";
        String sql = " SELECT * FROM `user` WHERE name=? and password=? ";
        PreparedStatement pstate = conn.prepareStatement(sql);
        pstate.setString(1, userName);
        pstate.setString(2, userPwd);
        ResultSet rsSet = pstate.executeQuery();

        while(rsSet.next()) {
            String name = rsSet.getString("name");
            String password = rsSet.getString("password");
            System.out.println(name+" "+password);  
        }
        rsSet.close();
        pstate.cancel();
        conn.close();
    }
}

五、HMAC-SHA256

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Sha256_mac {
    public static String sha256_mac(String message,String key){
        String outPut= null;
        try{
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(),"HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
            outPut = byteArrayToHexString(bytes);
        }catch (Exception e){
            System.out.println("Error HmacSHA256========"+e.getMessage());
        }
        return outPut;
    }
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder sb = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                sb.append('0');
            sb.append(stmp);
        }
        return sb.toString().toLowerCase();
    }

}

六、

七、

原文地址:https://www.cnblogs.com/Eleven-Liu/p/11148337.html