File signatures, also known as magic numbers, are unique sets of bytes at the beginning of files that help in identifying the file type regardless of the file’s extension. Validating a file’s signature is crucial for security and data integrity, especially in environments where file content should match its extension.
Here’s a list of some common file signatures with their corresponding extensions, followed by a C# example of how to validate a file’s signature based on its expected type:
Common File Signatures
- JPEG Image:
.jpeg, .jpg
–FF D8 FF
- PNG Image:
.png
–89 50 4E 47 0D 0A 1A 0A
- GIF Image:
.gif
–47 49 46 38
- TIFF Image:
.tiff
–49 49 2A 00
or4D 4D 00 2A
- BMP Image:
.bmp
–42 4D
- PDF Document:
.pdf
–25 50 44 46
- ZIP Archive:
.zip
–50 4B 03 04
or50 4B 05 06
or50 4B 07 08
- RAR Archive:
.rar
–52 61 72 21 1A 07 00
- 7z Archive:
.7z
–37 7A BC AF 27 1C
- MS Office/OpenOffice Documents:
.docx, .xlsx, .pptx
–50 4B 03 04
- MS Office 97-2003 Document:
.doc, .xls, .ppt
–D0 CF 11 E0 A1 B1 1A E1
- WAV Audio:
.wav
–52 49 46 46
- AVI Video:
.avi
–52 49 46 46
- MP3 Audio:
.mp3
–FF FB
or49 44 33
- FLV Video:
.flv
–46 4C 56 01
- Real Audio:
.ram
–2E 72 61 FD
- Real Media:
.rm
–2E 52 4D 46
- MPEG Video:
.mpeg, .mpg
–00 00 01 BA
or47 40
- QuickTime Video:
.mov
–00 00 00 14 66 74 79 70
- MIDI Audio:
.midi
–4D 54 68 64
- ISO Image:
.iso
–43 44 30 30 31
- Executable File:
.exe
–4D 5A
- ELF Executable:
.elf
–7F 45 4C 46
- VMDK File:
.vmdk
–4B 44 4D
- AIFF Audio:
.aiff
–46 4F 52 4D 00
- XML Document:
.xml
–3C 3F 78 6D 6C 20
- SQLite Database:
.sqlite
–53 51 4C 69
- Photoshop Document:
.psd
–38 42 50 53
- MP4 Video:
.mp4
–00 00 00 18 66 74 79 70
- AutoCAD Drawing:
.dwg
–41 43 31 30
C# Code to Validate File Signature
The following C# function checks the file signature by comparing the beginning bytes of the file to known signatures:
using System;
using System.Collections.Generic;
using System.IO;
public class FileSignatureValidation
{
private static Dictionary<string, List<byte[]>> fileSignatures = new Dictionary<string, List<byte[]>> {
{ ".jpeg", new List<byte[]> { new byte[] { 0xFF, 0xD8, 0xFF } } },
{ ".png", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
// Add more signatures here
};
public static bool ValidateFileSignature(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs))
{
var fileExt
= Path.GetExtension(filePath).ToLowerInvariant();
if (fileSignatures.ContainsKey(fileExt))
{
var headerBytes = br.ReadBytes(fileSignatures[fileExt][0].Length);
foreach (var sig in fileSignatures[fileExt])
{
if (headerBytes.SequenceEqual(sig))
{
return true;
}
}
}
return false;
}
}
}
public static void Main(string[] args)
{
var filePath = @"path\to\your\file.jpg";
bool isValid = ValidateFileSignature(filePath);
Console.WriteLine($"File signature validation: {isValid}");
}
}
This code initializes a dictionary with file signatures and checks if the beginning bytes of a file match any of the expected signatures for that file extension. You would need to expand the fileSignatures
dictionary to include more file types and their corresponding signatures.