通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法:

1. 通过后缀名,如exe,jpg,bmp,rar,zip等等。

2. 通过读取文件,获取文件的Content-type来判断。

3. 通过读取文件流,根据文件流中特定的一些字节标识来区分不同类型的文件。

4. 若是图片,则通过缩放来判断,可以缩放的为图片,不可以的则不是。

然而,在安全性较高的业务场景中,1,2两种方法的校验会被轻易绕过。

1. 伪造后缀名,如图片的,非常容易修改。

2. 伪造文件的Content-type,这个稍微复杂点,

3.较安全,但是要读取文件,并有16进制转换等操作,性能稍差,但能满足一定条件下对安全的要求,所以建议使用。

但是文件头的信息也可以伪造,截图如下,对于图片可以采用图片缩放或者获取图片宽高的方法避免伪造头信息漏洞。

  1. package com.nfschina.utils.file;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. import java.util.Map;
  7. import java.util.Map.Entry;
  8. import com.nfschina.utils.BaseException;
  9. /***********************************************************************
  10. *
  11. * Description: 主要用于判断文件的类型
  12. *
  13. ***********************************************************************/
  14. public class FileTools {
  15. public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();
  16. /*-----------------------------目前可以识别的类型----------------------------*/
  17. private static void getAllFileType()
  18. {
  19. FILE_TYPE_MAP.put("jpg", "FFD8FF"); //JPEG
  20. FILE_TYPE_MAP.put("png", "89504E47"); //PNG
  21. FILE_TYPE_MAP.put("gif", "47494638"); //GIF
  22. FILE_TYPE_MAP.put("tif", "49492A00"); //TIFF
  23. FILE_TYPE_MAP.put("bmp", "424D"); //Windows Bitmap
  24. FILE_TYPE_MAP.put("dwg", "41433130"); //CAD
  25. FILE_TYPE_MAP.put("html", "68746D6C3E"); //HTML
  26. FILE_TYPE_MAP.put("rtf", "7B5C727466"); //Rich Text Format
  27. FILE_TYPE_MAP.put("xml", "3C3F786D6C");
  28. FILE_TYPE_MAP.put("zip", "504B0304");
  29. FILE_TYPE_MAP.put("rar", "52617221");
  30. FILE_TYPE_MAP.put("psd", "38425053"); //PhotoShop
  31. FILE_TYPE_MAP.put("eml", "44656C69766572792D646174653A"); //Email [thorough only]
  32. FILE_TYPE_MAP.put("dbx", "CFAD12FEC5FD746F"); //Outlook Express
  33. FILE_TYPE_MAP.put("pst", "2142444E"); //Outlook
  34. FILE_TYPE_MAP.put("office", "D0CF11E0"); //office类型,包括doc、xls和ppt
  35. FILE_TYPE_MAP.put("mdb", "000100005374616E64617264204A"); //MS Access
  36. FILE_TYPE_MAP.put("wpd", "FF575043"); //WordPerfect
  37. FILE_TYPE_MAP.put("eps", "252150532D41646F6265");
  38. FILE_TYPE_MAP.put("ps", "252150532D41646F6265");
  39. FILE_TYPE_MAP.put("pdf", "255044462D312E"); //Adobe Acrobat
  40. FILE_TYPE_MAP.put("qdf", "AC9EBD8F"); //Quicken
  41. FILE_TYPE_MAP.put("pwl", "E3828596"); //Windows Password
  42. FILE_TYPE_MAP.put("wav", "57415645"); //Wave
  43. FILE_TYPE_MAP.put("avi", "41564920");
  44. FILE_TYPE_MAP.put("ram", "2E7261FD"); //Real Audio
  45. FILE_TYPE_MAP.put("rm", "2E524D46"); //Real Media
  46. FILE_TYPE_MAP.put("mpg", "000001BA"); //
  47. FILE_TYPE_MAP.put("mov", "6D6F6F76"); //Quicktime
  48. FILE_TYPE_MAP.put("asf", "3026B2758E66CF11"); //Windows Media
  49. FILE_TYPE_MAP.put("mid", "4D546864"); //MIDI (mid)
  50. }
  51. /**
  52. * 通过读取文件头部获得文件类型
  53. * @param file
  54. * @return 文件类型
  55. * @throws BaseException
  56. */
  57. public static String getFileType(File file) throws BaseException{
  58. getAllFileType();
  59. String fileExtendName = null;
  60. FileInputStream is;
  61. try {
  62. is = new FileInputStream(file);
  63. byte[] b = new byte[16];
  64. is.read(b,0, b.length);
  65. String filetypeHex = String.valueOf(bytesToHexString(b));
  66. Iterator<Entry<String, String>> entryiterator = FILE_TYPE_MAP.entrySet().iterator();
  67. while (entryiterator.hasNext()) {
  68. Entry<String,String> entry = entryiterator.next();
  69. String fileTypeHexValue = entry.getValue();
  70. if (filetypeHex.toUpperCase().startsWith(fileTypeHexValue)) {
  71. fileExtendName = entry.getKey();
  72. if(fileExtendName.equals("office")) {
  73. fileExtendName = getOfficeFileType(is);
  74. }
  75. is.close();
  76. break;
  77. }
  78. }
  79. // 如果不是上述类型,则判断扩展名
  80. if(fileExtendName == null)
  81. {
  82. String fileName = file.getName();
  83. // 如果无扩展名,则直接返回空串
  84. if(-1 == fileName.indexOf("."))
  85. {
  86. return "";
  87. }
  88. // 如果有扩展名,则返回扩展名
  89. return fileName.substring(fileName.indexOf(".") + 1);
  90. }
  91. is.close();
  92. return fileExtendName;
  93. } catch (Exception exception) {
  94. throw new BaseException(exception.getMessage(), exception);
  95. }
  96. }
  97. /**
  98. * 判断office文件的具体类型
  99. * @param fileInputStream
  100. * @return office文件具体类型
  101. * @throws BaseException
  102. */
  103. private static String getOfficeFileType(FileInputStream fileInputStream) throws BaseException{
  104. String officeFileType = "doc";
  105. byte[] b = new byte[512];
  106. try {
  107. fileInputStream.read(b, 0, b.length);
  108. String filetypeHex = String.valueOf(bytesToHexString(b));
  109. String flagString = filetypeHex.substring(992, filetypeHex.length());
  110. if(flagString.toLowerCase().startsWith("eca5c")){
  111. officeFileType = "doc";
  112. } else if(flagString.toLowerCase().startsWith("fdffffff09")){
  113. officeFileType = "xls";
  114. } else if(flagString.toLowerCase().startsWith("09081000000")){
  115. officeFileType = "xls";
  116. } else {
  117. officeFileType = "ppt";
  118. }
  119. return officeFileType;
  120. } catch (Exception exception) {
  121. throw new BaseException(exception.getMessage(), exception);
  122. }
  123. }
  124. /**
  125. * 获得文件头部字符串
  126. * @param src
  127. * @return
  128. */
  129. private static String bytesToHexString(byte[] src){
  130. StringBuilder stringBuilder = new StringBuilder();
  131. if (src == null || src.length <= 0) {
  132. return null;
  133. }
  134. for (int i = 0; i < src.length; i++) {
  135. int v = src[i] & 0xFF;
  136. String hv = Integer.toHexString(v);
  137. if (hv.length() < 2) {
  138. stringBuilder.append(0);
  139. }
  140. stringBuilder.append(hv);
  141. }
  142. return stringBuilder.toString();
  143. }
  144. public static void main(String[] args)
  145. {
  146. File file = new File("E:/新闻公告.pdm");
  147. FileInputStream is;
  148. try{
  149. is = new FileInputStream(file);
  150. byte[] b = new byte[16];
  151. is.read(b,0, b.length);
  152. //            String filetypeHex = String.valueOf(bytesToHexString(b));
  153. String fileName = file.getName();
  154. System.out.println(fileName.substring(fileName.indexOf(".") + 1));
  155. }catch(Exception e)
  156. {
  157. e.printStackTrace();
  158. }
  159. }

JAVA对文件类型的校验的更多相关文章

  1. Java判断文件类型

    通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法: 1. 通过后缀名,如exe,jpg,bmp,rar,zip等等. 2. 通过读取文件,获取文件的Content-type来 ...

  2. JAVA生成文件的md5校验值

    这里使用了lombok打印日志,也可以不用 import java.io.File; import java.io.FileInputStream; import java.io.IOExceptio ...

  3. JAVA计算文件的crc32校验码

    import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...

  4. Java根据字节数据判断文件类型

    通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法: 1. 通过后缀名,如exe,jpg,bmp,rar,zip等等. 2. 通过读取文件,获取文件的Content-type来 ...

  5. [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. java读取各类型的文件

    java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...

  7. Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB

    Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...

  8. 用java流方式判断文件类型

    这个方法只能在有限的范围内有效.并不是万金油 比如 图片类型判断,音频文件格式判断,视频文件格式判断等这种肯定是2进制且专业性很强的文件类型判断. 下面给出完整版代码 首先是文件类型枚取 packag ...

  9. 通过后缀名和MIME-TYPE检查实现文件类型校验

    前言 文件上传是一个在开发中很常见的需求场景,通常出于安全考虑,我们会对上传的文件进行类型校验,其中常见的有后缀名校验,mime-type校验 话不多说,直接上代码 1.首先定义允许上传的文件类型白名 ...

随机推荐

  1. 为什么那么多人想开发一元夺宝类app?

    别拿你的无知和愚蠢,来证明主观的判断! 国人对一切事物具有怀疑的本性是好的, 但是若不建立于科学的分析方法, 那就是愚昧! 身边有朋友玩夺宝投入较多,产出较少,于是向我求助.想从数据分析的角度知道到底 ...

  2. shipyard安装

    1.Start an data volume instance of RethinkDB: # docker run -it -d --name shipyard-rethinkdb-data \ - ...

  3. PAT 1011. A+B和C (15)

    给定区间[-231, 231]内的3个整数A.B和C,请判断A+B是否大于C. 输入格式: 输入第1行给出正整数T(<=10),是测试用例的个数.随后给出T组测试用例,每组占一行,顺序给出A.B ...

  4. ubuntu Apache 2命令

    Task: Start Apache 2 Server /启动apache服务# /etc/init.d/apache2 startor$ sudo /etc/init.d/apache2 start ...

  5. 前端面试——css篇

    css盒子模型 在W3C模型中: 总宽度 = margin-left + border-left + padding-left + width + padding-right + border-rig ...

  6. Linux常用命令笔记

    ~ 我的home目录/ 系统根目录进入home目录:cd \进入跟目录:cd /Maven编译:mvn clean deploy -U -Dmaven.test.skip=true dependenc ...

  7. C# 6.0

    C# 6.0 的新语法特性   回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都 ...

  8. [py]给函数传递数组和字典

    一 , 1.1传元组 def fun(x): print x t=(1,2) fun(t) 1.2传元组 #传元组 def fun(x,y): print x,y # t=(1,2) t=(1,2,3 ...

  9. 解决Kafka-1194问题

    生产环境中使用Kafka作为日志处理的中间件,系统结构是这样的.自12月上线一个多月来,系统运行稳定. 用过kafka的都知道,Kafka产生的消息全部存储到硬盘文件中,并且在消息被消费后不会被立即删 ...

  10. Tomcat 内存溢出对应解决方式

    1.Tomcat内存溢出的原因 生产环境中Tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三 ...