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.首先定义允许上传的文件类型白名 ...
随机推荐
- JavaScript Date 对象
JavaScript Date 对象 Date 对象 Date 对象用于处理日期与实际. 创建 Date 对象: new Date(). 以上四种方法同样可以创建 Date 对象: var d = n ...
- JQuery常用方法(均实践过)
1,使用jquery修改html元素的值 a,修改form的action的值(即修改html的属性值) 这个可以扩展为修改html元素的属性值的方法,使用的$("#id").att ...
- EEG: electrode positions & Broadmann atlas
Source: http://www.brainm.com/software/pubs/dg/BA_10-20_ROI_Talairach/nearesteeg.htm Area LEFT RIG ...
- 搜索引擎关键词劫持之asp篇
摘要:关键词劫持(黑帽seo)其实原理很简单:搜索引擎关键词劫持的过程实际上就是,修改肉鸡站点(webshell站点)A的首页(希望被搜索引擎收录的页面,一般情况下是首页),使之做出判断... 黑帽S ...
- BZOJ 2733 【HNOI2012】 永无乡
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- android 中退出程序的两种方式
转自:http://blog.sina.com.cn/s/blog_5da93c8f0100t76l.html 思考:如何安全的退出程序? finish是Activity的类,仅仅针对Activity ...
- C# where用法
where 子句用于指定类型约束,这些约束可以作为泛型声明中定义的类型参数的变量. 1.接口约束. 例如,可以声明一个泛型类 MyGenericClass,这样,类型参数 T 就可以实现 ICompa ...
- IBM WebSphere MQ 7.5基本用法
一.下载7.5 Trial版本 http://www.ibm.com/developerworks/downloads/ws/wmq/ 这是下载网址,下载前先必须注册IBM ID,下载完成后一路Nex ...
- lecture2-NN结构的主要类型的概述和感知机
Hinton课程第二课 一.NN结构的主要类型的概述 这里的结构就是连接在一起的神经元.目前来说,在实际应用中最常见的NN就是前向NN,他是将数据传递给输入单元,通过隐藏层最后到输出层的单元:一个更有 ...
- C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...