美文网首页
文件上传与魔数判断

文件上传与魔数判断

作者: 小胖学编程 | 来源:发表于2021-06-15 14:52 被阅读0次

而对于上传文件来说,不能简单的通过后缀名来判断文件的类型,因为恶意攻击可以将可执行文件的后缀名称改为图片或者其他格式,诱导用户执行,因此,判断上传文件的类型需要更安全的方式。

1. 文件上传的API

引入依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

API说明

Apache commons io FileUtils、IOUtils 详解

测试代码:

FileUtils.readFileToByteArray(new File("/Users/libai/Documents/xwc.jpeg"));

2. 文件魔数

与Java的class文件类似,很多类型的文件,起始的几个字节内容都是固定的,跟据这几个字节的内容,就可以判断文件的类型,这几个字节也被称为“魔数”,比如class文件的魔数就是“CAFEBABE”。

通过魔数判断文件类型便是一种更安全的方式,其示例源码如下。

魔数枚举类:

import lombok.Getter;

@Getter
public enum FileType {
    /**
     * JPEG
     */
    JPEG("FFD8FF"),
    /**
     * PNG
     */
    PNG("89504E47"),
    /**
     * GIF
     */
    GIF("47494638"),
    /**
     * TIFF
     */
    TIFF("49492A00"),
    /**
     * Windows bitmap
     */
    BMP("424D"),
    /**
     * CAD
     */
    DWG("41433130"),
    /**
     * Adobe photoshop
     */
    PSD("38425053"),
    /**
     * Rich Text Format
     */
    RTF("7B5C727466"),
    /**
     * XML
     */
    XML("3C3F786D6C"),
    /**
     * HTML
     */
    HTML("68746D6C3E"),
    /**
     * Outlook Express
     */
    DBX("CFAD12FEC5FD746F "),
    /**
     * Outlook
     */
    PST("2142444E"),
    /**
     * doc;xls;dot;ppt;xla;ppa;pps;pot;msi;sdw;db
     */
    OLE2("0xD0CF11E0A1B11AE1"),
    /**
     * Microsoft Word/Excel
     */
    XLS_DOC("D0CF11E0"),
    /**
     * Microsoft Access
     */
    MDB("5374616E64617264204A"),
    /**
     * Word Perfect
     */
    WPB("FF575043"),
    /**
     * Postscript
     */
    EPS_PS("252150532D41646F6265"),
    /**
     * Adobe Acrobat
     */
    PDF("255044462D312E"),
    /**
     * Windows Password
     */
    PWL("E3828596"),
    /**
     * ZIP Archive
     */
    ZIP("504B0304"),
    /**
     * ARAR Archive
     */
    RAR("52617221"),
    /**
     * WAVE
     */
    WAV("57415645"),
    /**
     * AVI
     */
    AVI("41564920"),
    /**
     * Real Audio
     */
    RAM("2E7261FD"),
    /**
     * Real Media
     */
    RM("2E524D46"),
    /**
     * Quicktime
     */
    MOV("6D6F6F76"),
    /**
     * Windows Media
     */
    ASF("3026B2758E66CF11"),
    /**
     * MIDI
     */
    MID("4D546864");

    private String value;

    FileType(String value) {
        this.value = value;
    }
}

魔数校验类

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileUtil {


    /**
     * 判断文件类型
     */
    public static FileType getType(String filePath) throws IOException {//获取文件头

        String fileHead = getFileHeader(filePath);
        if (fileHead != null && fileHead.length() > 0) {
            fileHead = fileHead.toUpperCase();

            FileType[] fileTypes = FileType.values();
            for (FileType type : fileTypes) {
                if (fileHead.startsWith(type.getValue())) {
                    return type;

                }

            }

        }
        return null;
    }


    public static FileType getType(byte[] bytes) throws IOException {//获取文件头

        String fileHead = bytesToHex(bytes);
        if (fileHead != null && fileHead.length() > 0) {
            fileHead = fileHead.toUpperCase();

            FileType[] fileTypes = FileType.values();
            for (FileType type : fileTypes) {
                if (fileHead.startsWith(type.getValue())) {
                    return type;
                }

            }

        }
        return null;
    }


    /**
     * 读取文件头
     */
    private static String getFileHeader(String filePath) throws IOException {
        byte[] b = new byte[28];

        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
            inputStream.read(b, 0, 28);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return bytesToHex(b);
    }

    /**
     * 将字节数组转换成16进制字符串
     */
    public static String bytesToHex(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();
    }
}

相关文章

  • 文件上传与魔数判断

    而对于上传文件来说,不能简单的通过后缀名来判断文件的类型,因为恶意攻击可以将可执行文件的后缀名称改为图片或者其他格...

  • Java Class文件格式

    魔数与Class文件版本 每个Class文件的头4个字节称为魔数(Magic Number),作用是确定这个文件是...

  • 《深入理解Java虚拟机》学习笔记(四)(类文件结构)

    魔数与Class文件的版本 魔数(Magic Number)每个Class文件的头4个字节唯一作用是确定这个文件是...

  • django-文件上传

    文件上传的思路: 文件上传:是否有文件进行判断 如果有:给文件一个上传路径,并利用uuid生成一个新的名字,与上传...

  • django---文件上传

    文件上传的思路: 文件上传:是否有文件进行判断 如果有:给文件一个上传路径,并利用uuid生成一个新的名字,与上传...

  • C# 判断文件、文件夹是否存在

    //在上传文件时经常要判断文件夹是否存在,如果存在就上传文件,否则新建文件夹再上传文件判断语句为if (Syste...

  • 13. 字节码文件解析

    魔数 魔数:所有的.class字节码文件的前4个字节都是魔数,魔数值为固定值:0xCAFEBABE 版本信息 魔数...

  • 2018-06-01

    总共上传的文件数、成功上传的文件数、上传文件的成功率、上传文件所花的时间、平均用时以及每秒查询数(请求数) 上传1...

  • FileUpload选择特定格式文件上传(判断文件的真正类型)

    打开读取文件,根据文件的位长判断文件的类型: //判断上传文件的真正类型 private bool IsAllow...

  • AliyunOss如何判断Obeject是否存在

    AliyunOss如何判断Obeject是否存在 /** * 判断上传文件是否存在 */ public stati...

网友评论

      本文标题:文件上传与魔数判断

      本文链接:https://www.haomeiwen.com/subject/yayzeltx.html