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.首先定义允许上传的文件类型白名 ...
随机推荐
- qau-国庆七天乐——A
A - Who's in the Middle //先吐槽一波vj,不知道怎么回事,bits/stdc++.h不能用了...坑爹 7225007 upstar A Compile Error ...
- [No000022]他们说:得诺贝尔奖到底有多难?
- ie 7/8不支持trim的属性的解决方案
if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...
- 多项式FFT相关模板
自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...
- 在Mac mini上安装 ESXi 5.5
Mac mini 是 mid 2011 版本的, 安装原版ESXi 5.5 update 1 非常顺利, 没遇到任何问题. 提示: 1. 安装会初始化整个硬盘, 有数据要先备份 2. ESXi只使用有 ...
- PAT 1009. 说反话 (20)
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区 ...
- Windows Server 2008 R2中的ASP.NET环境架设
.NET Framework的部分功能在Windows Server 2008 R2得到支持,包括:.NET 2/3/3.5的子集和ASP.NET.另外,PowerShell也在Server Core ...
- BZOJ 3110 【Zjoi2013】 K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置 ...
- Java多线程总结(二)锁、线程池
掌握Java中的多线程,必须掌握Java中的各种锁,以及了解Java中线程池的运用.关于Java多线程基础总结可以参考我的这篇博文Java多线程总结(一)多线程基础 转载请注明出处——http://w ...
- js从0开始构思表情插件
前言: 由于公司开发项目需要用到表情插件,在网上百度了好久,很多表情插件,都是需要引用好多js文件,也没有现成的demo可以使用,还有一些插件是引用好多图片,每一个表情都要重新请求一下.为了这样一个功 ...