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(); } }
六、
七、
分类:
show me the code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探