0

我有一个上传例程,我将前几个字节读入数组并将其转换为十六进制字符串以获取文件签名。

我一直在将前 4 个字节读入数组,一切似乎都很好,直到遇到 .zip 文件和 .docx 文件的问题。它们在前 4 个字节中都具有相同的签名:“50-4b-03-04”。

所以我查看了下一个字节,对于 .docx,它是“14”,但它也在一些 .zip 文件中。我查找了这个文件签名,发现这个序列适用于很多文件类型,包括 JAR、ZIP、DOCX、XSLX 和 Open Office 文档。

有谁知道读取文件签名并准确确定文件类型的好方法?Windows 如何知道差异?它必须不仅仅是前 4 个字节。我正在阅读文件上传的文件签名,以确保只允许上传批准的文件类型。

4

1 回答 1

0

我所做的是将文件签名放入数据库,放入文件类型的签名长度和扩展名。如果文件没有扩展名,则不会上传。如果文件扩展名已从签名更改,则例程将拒绝该文件。这是提取签名并进行比较的例程中的代码:

using var fileStream = file.OpenReadStream();
var signature = _context.FileSignatures.Select(f => new { f.FileSignature, f.AllowedFileType.FileExtension, f.SignatureLength })
                                       .Where(x => x.FileExtension == fileType);

byte[] bytes = new byte[signature.Max(x => x.SignatureLength)];
fileStream.Read(bytes, 0, signature.Max(x => x.SignatureLength));

string hexData = BitConverter.ToString(bytes);
var foundFile = await signature.FirstAsync(x => x.FileSignature == hexData);

return foundFile.FileExtension;

文件签名存储在表中,如下所示:

File Extension           FileSignature        SignatureLength
.PDF                     25-50-44-46          4

这样我可以确保读取签名的最大字节数并获取扩展名。如果我想包含更多文件,我只需将它们添加到数据库中。

于 2020-07-07T21:33:07.257 回答