JAVA对文件类型的校验
通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法:
1. 通过后缀名,如exe,jpg,bmp,rar,zip等等。
2. 通过读取文件,获取文件的Content-type来判断。
3. 通过读取文件流,根据文件流中特定的一些字节标识来区分不同类型的文件。
4. 若是图片,则通过缩放来判断,可以缩放的为图片,不可以的则不是。
然而,在安全性较高的业务场景中,1,2两种方法的校验会被轻易绕过。
1. 伪造后缀名,如图片的,非常容易修改。
2. 伪造文件的Content-type,这个稍微复杂点,
3.较安全,但是要读取文件,并有16进制转换等操作,性能稍差,但能满足一定条件下对安全的要求,所以建议使用。
但是文件头的信息也可以伪造,截图如下,对于图片可以采用图片缩放或者获取图片宽高的方法避免伪造头信息漏洞。
- package com.nfschina.utils.file;
- import java.io.File;
- import java.io.FileInputStream;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Map.Entry;
- import com.nfschina.utils.BaseException;
- /***********************************************************************
- *
- * Description: 主要用于判断文件的类型
- *
- ***********************************************************************/
- public class FileTools {
- public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();
- /*-----------------------------目前可以识别的类型----------------------------*/
- 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)
- }
- /**
- * 通过读取文件头部获得文件类型
- * @param file
- * @return 文件类型
- * @throws BaseException
- */
- public static String getFileType(File file) throws BaseException{
- getAllFileType();
- String fileExtendName = null;
- FileInputStream is;
- try {
- is = new FileInputStream(file);
- byte[] b = new byte[16];
- is.read(b,0, b.length);
- String filetypeHex = String.valueOf(bytesToHexString(b));
- Iterator<Entry<String, String>> entryiterator = FILE_TYPE_MAP.entrySet().iterator();
- while (entryiterator.hasNext()) {
- Entry<String,String> entry = entryiterator.next();
- String fileTypeHexValue = entry.getValue();
- if (filetypeHex.toUpperCase().startsWith(fileTypeHexValue)) {
- fileExtendName = entry.getKey();
- if(fileExtendName.equals("office")) {
- fileExtendName = getOfficeFileType(is);
- }
- is.close();
- break;
- }
- }
- // 如果不是上述类型,则判断扩展名
- if(fileExtendName == null)
- {
- String fileName = file.getName();
- // 如果无扩展名,则直接返回空串
- if(-1 == fileName.indexOf("."))
- {
- return "";
- }
- // 如果有扩展名,则返回扩展名
- return fileName.substring(fileName.indexOf(".") + 1);
- }
- is.close();
- return fileExtendName;
- } catch (Exception exception) {
- throw new BaseException(exception.getMessage(), exception);
- }
- }
- /**
- * 判断office文件的具体类型
- * @param fileInputStream
- * @return office文件具体类型
- * @throws BaseException
- */
- private static String getOfficeFileType(FileInputStream fileInputStream) throws BaseException{
- String officeFileType = "doc";
- byte[] b = new byte[512];
- try {
- fileInputStream.read(b, 0, b.length);
- String filetypeHex = String.valueOf(bytesToHexString(b));
- String flagString = filetypeHex.substring(992, filetypeHex.length());
- if(flagString.toLowerCase().startsWith("eca5c")){
- officeFileType = "doc";
- } else if(flagString.toLowerCase().startsWith("fdffffff09")){
- officeFileType = "xls";
- } else if(flagString.toLowerCase().startsWith("09081000000")){
- officeFileType = "xls";
- } else {
- officeFileType = "ppt";
- }
- return officeFileType;
- } catch (Exception exception) {
- throw new BaseException(exception.getMessage(), exception);
- }
- }
- /**
- * 获得文件头部字符串
- * @param src
- * @return
- */
- private 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();
- }
- public static void main(String[] args)
- {
- File file = new File("E:/新闻公告.pdm");
- FileInputStream is;
- try{
- is = new FileInputStream(file);
- byte[] b = new byte[16];
- is.read(b,0, b.length);
- // String filetypeHex = String.valueOf(bytesToHexString(b));
- String fileName = file.getName();
- System.out.println(fileName.substring(fileName.indexOf(".") + 1));
- }catch(Exception e)
- {
- e.printStackTrace();
- }
- }
JAVA对文件类型的校验的更多相关文章
- Java判断文件类型
通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法: 1. 通过后缀名,如exe,jpg,bmp,rar,zip等等. 2. 通过读取文件,获取文件的Content-type来 ...
- JAVA生成文件的md5校验值
这里使用了lombok打印日志,也可以不用 import java.io.File; import java.io.FileInputStream; import java.io.IOExceptio ...
- JAVA计算文件的crc32校验码
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...
- Java根据字节数据判断文件类型
通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法: 1. 通过后缀名,如exe,jpg,bmp,rar,zip等等. 2. 通过读取文件,获取文件的Content-type来 ...
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- java读取各类型的文件
java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...
- Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB
Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...
- 用java流方式判断文件类型
这个方法只能在有限的范围内有效.并不是万金油 比如 图片类型判断,音频文件格式判断,视频文件格式判断等这种肯定是2进制且专业性很强的文件类型判断. 下面给出完整版代码 首先是文件类型枚取 packag ...
- 通过后缀名和MIME-TYPE检查实现文件类型校验
前言 文件上传是一个在开发中很常见的需求场景,通常出于安全考虑,我们会对上传的文件进行类型校验,其中常见的有后缀名校验,mime-type校验 话不多说,直接上代码 1.首先定义允许上传的文件类型白名 ...
随机推荐
- java 关于多线程高并发方面
转有关的文章链接: Java 高并发一:前言: http://www.jb51.net/article/92358.htm Java 高并发二:多线程基础详细介绍 http://www.jb51.ne ...
- Zygote进程【3】——SystemServer的诞生
在ZygoteInit的main()方法中做了几件大事,其中一件便是启动Systemserver进程,代码如下: @/frameworks/base/core/Java/com/Android/int ...
- 千位分隔符(js 实现)
最近被同事问到js如何实现给长数字添加千位分隔符,即 1344444 ---> 13,444,444 这是一个很常见的前端面试题.看起来简单,刚开始我都懒得写. 仔细一想,挺考逻辑的,实现方法有 ...
- Python的高级特性5:谈谈python的动态属性
正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性. 看下面一种常见的get/set操作 In [174]: class ...
- Docker简明教程(以安装wget程序为例)
本文计划: 一.安装Docker(Centos) 二.注册Docker官网帐号 三.下载基础centos镜像,安装需要的软件和环境后,push到自己的repository 一.安装Docker(Cen ...
- Java集合系列:-----------01集合的整体框架
内容来自:http://www.cnblogs.com/skywang12345/p/3308498.html Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映 ...
- BZOJ 1014 【JSOI2008】 火星人prefix
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- JavaScript的闭包和内存泄漏问题
闭包 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html JavaScript中必须提到的功能最强大的抽象 ...
- Typescript 其实就想排个序和枚举取数
Typescript里的sort和C#差不多,但是略有不太一样,反正官方文档没说明白,就自己研究吧 list =list.sort((n1,n2) => { if(n1 > n2) { r ...
- (转)c# 解析JSON的几种办法
来自:http://blog.csdn.net/gaofang2009/article/details/6073029 欲成为海洋大师,必知晓海中每一滴水的真名. 刚开始只是想找一个转换JSON数组的 ...