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.首先定义允许上传的文件类型白名 ...
随机推荐
- uva10160 Servicing Stations
The input consists of more than one description of town (but totally, less than ten descriptions). E ...
- eclipse无法导入Android工程的现象与解决办法
最近在新导入一个Android工程时遇见了已有工程无法导入的情况.具体的现象就是每次导入时的导入窗口很快消失,而在eclipse的package explorer中却没有增加新导入的工程文件夹,没有其 ...
- Anyconnect的VPN环境部署(1)-OpenConnect server(ocserv)服务安装
打算在公司IDC机房部署一套VPN环境,经过考虑,最终决定采用Cisco下的开源技术AnyConnect.AnyConnect的优势有:1)长连接,待机不会断开:2)速度快,稳定性好:3)安全性好,全 ...
- githup上传代码
把自己本地东西上传到GitHup上. 本文内容来自于http://blog.csdn.net/yuanzichao/article/details/44922593 1.安装msysgit和Torto ...
- Codevs 1506 传话(floyd大法好)。
1506 传话 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 一个朋友网络,如果a认识b,那么如果a第 ...
- 截取视图某一段另存为部分视图(Partial View)
在做ASP.NET MVC后台管理程序时,根据程序需要,Isus.NET需要实现一个功能,就是动态截取视图某一段另存为部分视图Partial View. 思路为在视图中,使用jQury的程序截图以及P ...
- nfs客户端报错解决Stale file handle
NFS故障: 场景:客户端挂载是好的.服务端磁盘满了,重新给挂了一快.客户端df -h nfs挂载消失. 客户端报错:Stale file handle 现象如下: [root@test63-spri ...
- Linux 信号详解四(pause,alarm)
pause函数 --将进程置为可中断睡眠状态,然后它调用内核函数schedule(),使linux进程调度器找到另一个进程来运行. --pause使调用者进程挂起,知道一个信号被捕获. alarm函数 ...
- codevs 2651 孔子教学——同桌
2651 孔子教学--同桌 题目描述 Description 孔子是我国古代著名的教育家.他有先见之明,可以判断学生出师以后给他带来的声望.声望共有三种"G""M&quo ...
- Linux学习笔记-Ubuntu添加右键菜单打开终端
1.进入个人目录(如/home/batsing,下文缩写成 ~ ):设置显示隐藏文件,或使用命令行:2.进入 ~/.gnome2/nautilus-scripts 文件夹,新建一个文件,名为 term ...