检测受密码保护的PPT和XLS文档



我找到了这个答案 https://stackoverflow.com/a/14336292/1537195 它提供了一种检测DOC和XLS文件密码保护的好方法。

//Flagged with password
if (bytes.Skip(0x20c).Take(1).ToArray()[0] == 0x2f) return true; //XLS 2003
if (bytes.Skip(0x214).Take(1).ToArray()[0] == 0x2f) return true; //XLS 2005
if (bytes.Skip(0x20B).Take(1).ToArray()[0] == 0x13) return true; //DOC 2005

但是,它似乎并没有涵盖所有XLS文件,我也在寻找一种以相同方式检测PPT文件的方法。无论如何知道要查看这些文件类型的哪些字节吗?

我将PowerPoint演示文稿保存为.ppt和.pptx,打开它们所需的密码和没有密码,在7-Zip中打开它们并得出初步结论

  • .pptx没有密码的文件始终使用标准的.zip文件格式
  • .ppt文件是复合文档
  • .pptx带有密码的文件也 复合文档
  • 所有带密码的复合文档都包含一个名为 *加密* 的条目

若要运行此代码,需要安装 NuGet 包 OpenMcdf。这是我能找到的第一个用于阅读 CompoundDocuments 的 C# 库。

using OpenMcdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _22916194
{
    //http://stackoverflow.com/questions/22916194/detecing-password-protected-ppt-and-xls-documents
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var file in args.Where(File.Exists))
            {
                switch (Path.GetExtension(file))
                {
                    case ".ppt":
                    case ".pptx":
                        Console.WriteLine($"* {file} " +  (HasPassword(file) ? "is " : "isn't ") + "passworded");
                        Console.WriteLine();
                        break;
                    default:
                        Console.WriteLine($" * Unknown file type: {file}");
                        break;
                }
            }
            Console.ReadLine();
        }
        private static bool HasPassword(string file)
        {
            try
            {
                using (var compoundFile = new CompoundFile(file))
                {
                    var entryNames = new List<string>();
                    compoundFile.RootStorage.VisitEntries(e => entryNames.Add(e.Name), false);
                    //As far as I can see, only passworded files contain an entry with a name containing Encrypt
                    foreach (var entryName in entryNames)
                    {
                        if (entryName.Contains("Encrypt"))
                            return true;
                    }
                    compoundFile.Close();
                }
            }
            catch (CFFileFormatException) {
                //This is probably a .zip file (=unprotected .pptx)
                return false;
            }
            return false;
        }
    }
}

您应该能够扩展此代码以处理其他 Office 格式。顶部的结论应该成立,除了您需要在 CompoundDocument 中查找一些其他数据,而不是包含 *Encrypt* 的文件名(我快速浏览了.doc文件,它似乎并不完全相同)。

最新更新