文章目录

  • 前言
  • 判断上传的是否是图片
    • 通过后缀名进行判断
    • 通过文件头
    • 通过ImageIO判断
  • 图片文件的安全检查处理
    • 给图片加水印

前言

在web开发中,肯定会有一些图片上传的功能,如果仅仅是通过页面端进行控制是远远不够的,完全可以直接调用后台的接口,将一些病毒文件上传到服务器,如果不进行校验,后果不堪设想!

判断上传的是否是图片

通过后缀名进行判断

这层校验应该说是最基本的校验了,看下文件的后缀名是否符合要求的格式。

String fileType= "";
int i = fileName.lastIndexOf('.');
if (i > 0) {fileType= fileName.substring(i+1);
}
//...
if("jpg".equals(fileType) || "png".equals(fileType) ....){//your code
}

这种非常的不靠谱,完全可以修改文件的后缀名绕过检验。

通过文件头

根据文件的前面几个字节,即常说的魔术数字进行判断,不同文件类型的开头几个字节

// 获得文件头部字符串public static String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder();if (src == null || src.length <= 0) {return null;}for (int i = 0; i < src.length; i++) {int v = src[i] & 0xFF;String hv = Integer.toHexString(v);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}

不同文件的头魔术数字

private static void getAllFileType()     {     FILE_TYPE_MAP.put("jpg", "FFD8FF"); //JPEG      FILE_TYPE_MAP.put("png", "89504E47"); //PNG      FILE_TYPE_MAP.put("gif", "47494638"); //GIF     FILE_TYPE_MAP.put("tif", "49492A00"); //TIFF    FILE_TYPE_MAP.put("bmp", "424D"); //Windows Bitmap     FILE_TYPE_MAP.put("dwg", "41433130"); //CAD   FILE_TYPE_MAP.put("html", "68746D6C3E"); //HTML    FILE_TYPE_MAP.put("rtf", "7B5C727466"); //Rich Text Format    FILE_TYPE_MAP.put("xml", "3C3F786D6C");     FILE_TYPE_MAP.put("zip", "504B0304");     FILE_TYPE_MAP.put("rar", "52617221");     FILE_TYPE_MAP.put("psd", "38425053"); //PhotoShop  FILE_TYPE_MAP.put("eml", "44656C69766572792D646174653A"); //Email [thorough only]   FILE_TYPE_MAP.put("dbx", "CFAD12FEC5FD746F"); //Outlook Express   FILE_TYPE_MAP.put("pst", "2142444E"); //Outlook      FILE_TYPE_MAP.put("office", "D0CF11E0"); //office类型,包括doc、xls和ppt     FILE_TYPE_MAP.put("mdb", "000100005374616E64617264204A"); //MS Access     FILE_TYPE_MAP.put("wpd", "FF575043"); //WordPerfect   FILE_TYPE_MAP.put("eps", "252150532D41646F6265");     FILE_TYPE_MAP.put("ps", "252150532D41646F6265");     FILE_TYPE_MAP.put("pdf", "255044462D312E"); //Adobe Acrobat   FILE_TYPE_MAP.put("qdf", "AC9EBD8F"); //Quicken  FILE_TYPE_MAP.put("pwl", "E3828596"); //Windows Password FILE_TYPE_MAP.put("wav", "57415645"); //Wave   FILE_TYPE_MAP.put("avi", "41564920");     FILE_TYPE_MAP.put("ram", "2E7261FD"); //Real Audio     FILE_TYPE_MAP.put("rm", "2E524D46"); //Real Media     FILE_TYPE_MAP.put("mpg", "000001BA"); //     FILE_TYPE_MAP.put("mov", "6D6F6F76"); //Quicktime     FILE_TYPE_MAP.put("asf", "3026B2758E66CF11"); //Windows Media    FILE_TYPE_MAP.put("mid", "4D546864"); //MIDI (mid)     }

此时有人把一个可执行的PHP文件的扩展名修改为PNG,然后再在前面补上”89 50″两个字节,就又绕开了这种验证方式,这种也是不靠谱的!

通过ImageIO判断

  • 通过ImageReader来解码这个file并返回一个BufferedImage对象,如果找不到合适的ImageReader则会返回null,我们可以认为这不是图片文件。
  • 另外如果能够正常的获取到一张图片的宽高属性,那肯定这是一张图片,因为非图片文件我们是获取不到它的宽高属性的。
/*** 通过读取文件并获取其width及height的方式,来判断判断当前文件是否图片,这是一种非常简单的方式。* @param imageFile* @return*/public static boolean isImage(File imageFile) {if (!imageFile.exists()) {return false;}Image img = null;try {img = ImageIO.read(imageFile);if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {return false;}return true;} catch (Exception e) {return false;} finally {img = null;}}

这种方式较安全!

图片文件的安全检查处理

通过上面的方法,确认上传的文件是图片了,但是如果在可以正常打开的图片里面加入非法代码或者病毒,那就非常危险了。那么怎么可以预防这种情况,既能够正常打开,又能获取图片的宽高等属性,可以对图片进行重写,新生成的图片不会有这种恶意代码了。

给图片加水印

    /*** 给图片添加水印、可设置水印图片旋转角度* @param iconPath   水印图片路径* @param srcImgPath 源图片路径* @param targerPath 目标图片路径* @param degree     水印图片旋转角度* @param width      宽度(与左相比)* @param height     高度(与顶相比)* @param clarity    透明度(小于1的数)越接近0越透明*/public static void waterMarkImageByIcon(String iconPath, String srcImgPath,String targerPath, Integer degree, Integer width, Integer height,float clarity) {OutputStream os = null;try {Image srcImg = ImageIO.read(new File(srcImgPath));System.out.println("width:" + srcImg.getWidth(null));System.out.println("height:" + srcImg.getHeight(null));BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);// 得到画笔对象Graphics2D g = buffImg.createGraphics();// 设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null),srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);if (null != degree) {// 设置水印旋转g.rotate(Math.toRadians(degree),(double) buffImg.getWidth() / 2,(double) buffImg.getHeight() / 2);}// 水印图象的路径 水印一般为gif或者png的,这样可设置透明度ImageIcon imgIcon = new ImageIcon(iconPath);// 得到Image对象。Image img = imgIcon.getImage();float alpha = clarity; // 透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));// 表示水印图片的位置g.drawImage(img, width, height, null);g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));g.dispose();os = new FileOutputStream(targerPath);// 生成图片ImageIO.write(buffImg, "JPG", os);System.out.println("添加水印图片完成!");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != os)os.close();} catch (Exception e) {e.printStackTrace();}}}/*** 给图片添加水印、可设置水印图片旋转角度* @param logoText   水印文字* @param srcImgPath 源图片路径* @param targerPath 目标图片路径* @param degree     水印图片旋转角度* @param width      宽度(与左相比)* @param height     高度(与顶相比)* @param clarity    透明度(小于1的数)越接近0越透明*/public static void waterMarkByText(String logoText, String srcImgPath,String targerPath, Integer degree, Integer width, Integer height,Float clarity) {// 主图片的路径InputStream is = null;OutputStream os = null;try {Image srcImg = ImageIO.read(new File(srcImgPath));BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);// 得到画笔对象// Graphics g= buffImg.getGraphics();Graphics2D g = buffImg.createGraphics();// 设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null),srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);if (null != degree) {// 设置水印旋转g.rotate(Math.toRadians(degree),(double) buffImg.getWidth() / 2,(double) buffImg.getHeight() / 2);}// 设置颜色g.setColor(Color.red);// 设置 Fontg.setFont(new Font("宋体", Font.BOLD, 30));float alpha = clarity;g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));// 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y) .g.drawString(logoText, width, height);g.dispose();os = new FileOutputStream(targerPath);// 生成图片ImageIO.write(buffImg, "JPG", os);System.out.println("添加水印文字完成!");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != is)is.close();} catch (Exception e) {e.printStackTrace();}try {if (null != os)os.close();} catch (Exception e) {e.printStackTrace();}}}public static void main(String[] args) throws IOException {waterMarkImageByIcon("d:/shuiyin.png", imagePath, "d:/result.png", 10, 100, 100, 0F);waterMarkByText("logo", imagePath, "d:/result1.png", 3, 100, 100, 0F);}

上面加水印,你可以将透明度调为0,乍一看跟原图一样,其实不是上面的那张原图了。

效果展示
原图:

加水印图片(水印透明度0.5):

加水印文字(水印透明度0.5):

Java对上传的图片进行格式校验以及安全性校验相关推荐

  1. java 图片格式校验_(转载)Java对上传的图片进行格式校验以及安全性校验

    文章目录 前言 判断上传的是否是图片 通过后缀名进行判断 通过文件头 通过ImageIO判断 图片文件的安全检查处理 给图片加水印 前言 在web开发中,肯定会有一些图片上传的功能,如果仅仅是通过页面 ...

  2. java 上传的图片大小为0_JAVA技术:上传图片的缩放处理

    图片上传到后,会根据情况将图片缩小成一个图标,我们可以利用java强大的图形处理功能,对上传的图片进行缩放处理. 下面的程序使用jdk1.4中最新的ImageIO对图片进行读写.使用AffineTra ...

  3. JAVA上传文件图片到服务器保存

    这里我记录一个比较简单方便操作的JAVA上传文件图片到服务器并且保存! 首先是页面 html的   我这是提交一个文件和类型 <div style="border: 1px solid ...

  4. java上传文件图片到服务器保存,Java上传文件图片到服务器的方法

    这里我记录一个比较简单方便操作的java上传文件图片到服务器并且保存,具体内容如下 首先是页面html的   我这是提交一个文件和类型 我是添加一张临时图片得到微信的media_id保存数据库! en ...

  5. Java 对上传文件进行魔数校验

    魔数这个词在不同领域代表不同的含义.在计算机领域,魔数有两个含义,一指用来判断文件类型的魔数(magic number):二指程序代码中的魔数,也称魔法值. 不是所有文件都有文件头的.一个.txt类型 ...

  6. Java判断上传的文件是否是图片,如果是就对上传的图片进行压缩

    1.导入依赖 <!-- 图片缩略图 -->             <dependency>                 <groupId>net.coobir ...

  7. java 微信开发图片发送,微信开发?Java上传Base64图片

    class="java">import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Log ...

  8. java上传png_java图片上传

    1 /***2 * 上传证明材料3 *@paramfiles4 *@paramrequest5 *@return 6 */ 7 @RequestMapping(value = "/bitch ...

  9. java 上传远程图片,java上传图片到另一台服务器上,怎么解决

    Java codepublic String upload(String dir, FormFile formFile) throws Exception { Date date = new Date ...

  10. Java 利用Graphics2D 合并图片(png格式可设置透明)

    利用Graphics2D 合并图片 效果如下: 图一图二合并成图三 tip:  需要上图的效果 frontgroud需要为png格式 附上代码: import javax.imageio.ImageI ...

最新文章

  1. linux telnet远程登录工具,Linux 远程登录(telnet ssh)
  2. 一个Java递归删除目录的方法
  3. python去噪算法
  4. Rime在linux下面的安装-还没写完
  5. python 硬件自动化测试_村长告诉你:Python实现性能自动化测试竟然如此简单
  6. 并发编程(二)线程并发工具类
  7. linux用于开发qt java_Linux下Qt程序的打包发布
  8. 将Unix时间戳字符串转换为可读日期
  9. 推荐!手把手教你使用Git(转)
  10. 天题系列:Substring with Concatenation of All Words
  11. 切割钢板计算机软件,板材切割优化软件钢板开料套料软件 V1.0 官方版
  12. java程序设计大赛acm_转载(ACM国际大学生程序设计大赛)
  13. 什么是https安全证书
  14. python脚本之对文件进行哈希校验
  15. 听歌识曲C++程序说明
  16. 设计模式 - 创建型模式_工厂方法模式
  17. python dataframe是什么_什么是Pandas的DataFrame?
  18. Flink 计算 TopN
  19. 操作系统总结(二)系统调用及系统结构
  20. 勒索软件攻击:如何使用加密来保护您的数据

热门文章

  1. 2020第六届上海市大学生网络安全大赛线上赛Misc-可乐加冰
  2. Linux alarm闹钟函数
  3. 中兴阅读在期刊杂志数字化、移动化上的探索
  4. iOS计算器:采用NSDecimalNumber 进行表达式的精准计算(计算字符串数学表达式)【案例:折扣计算器(完整demo源码)】
  5. Android仿自如客APP裸眼3D效果
  6. 谈一谈Normalize.css
  7. Markdown入门指南【我为什么要推荐你学习Markdown?】
  8. golang报错:slice bounds out of range
  9. 无论是要打牢计算机基础还是准备校招面试,这本书你不可错过!
  10. epub格式的电子书