1

我正在开发一个网站,该网站允许用户上传不同的文件格式。我们需要限制用户上传受密码保护的文件。

有没有办法在上传文件之前确定 Microsoft Office 文件(Word、Powerpoint 和 Excel)是否受密码保护?根据http://social.msdn.microsoft.com/Forums/en/oxmlsdk/thread/34701a34-f1d4-4802-9ce4-133f15039c69,我已经实现了以下内容,但它抛出了一个错误,说“文件包含损坏的数据” ,同时尝试打开受密码保护的文件。

 using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, false))
 {
     DocumentProtection dp =
         wordDoc.MainDocumentPart.DocumentSettingsPart.Settings.GetFirstChild<DocumentProtection>();
     if (dp != null && dp.Enforcement == DocumentFormat.OpenXml.OnOffValue.FromBoolean(true))
     {
         return true;
     }
 }

还有其他方法可以确定吗?

4

5 回答 5

5

试试这个代码:

public static Boolean IsProtected(String file)
{
    Byte[] bytes = File.ReadAllBytes(file);

    String prefix = Encoding.Default.GetString(bytes.Take(2).ToArray());

    // Zip and not password protected.
    if (prefix == "PK")
        return false;

    // Office format.
    if (prefix == "ÐÏ")
    {
        // XLS 2003
        if (bytes.Skip(0x208).Take(1).ToArray()[0] == 0xFE)
            return true;

        // XLS 2005
        if (bytes.Skip(0x214).Take(1).ToArray()[0] == 0x2F)
            return true;

        // DOC 2005
        if (bytes.Skip(0x20B).Take(1).ToArray()[0] == 0x13)
            return true;

        // Guessing
        if (bytes.Length < 2000)
            return false;

        // DOC/XLS 2007+
        String start = Encoding.Default.GetString(bytes.Take(2000).ToArray()).Replace("\0", " ");

        if (start.Contains("E n c r y p t e d P a c k a g e"))
            return true;

        return false;
    }

    // Unknown format.
    return false;
}
于 2013-01-15T22:01:12.353 回答
1

抱歉,我在这里聚会有点晚了。由于我还没有 50 名声望,所以我无法评论 Tomasso Belluzo 的回答,但是当我实施它时,我发现了以下内容:

  1. 要获取前缀,我使用 Encoding.UTF7.GetString
  2. 要检查“EncryptedPackage”,我使用 Encoding.Unicode.GetString 消除了删除所有 \0s 的需要
于 2019-10-07T11:31:06.273 回答
0

要回答这个问题:

为了判断文件是否受密码保护,您需要在浏览器中打开该文件并进行处理。目前,打开文件客户端的唯一机制是通过 HTML5 的 FileAPI,这不是普遍支持的。这意味着没有可靠的方法可以做到这一点。

现在,您可以在服务器上测试文件以确定它是否受密码保护,然后根据您的规则将其丢弃或保存。

顺便说一句,您提供的代码是服务器端代码。只需对其进行修改以捕获损坏的异常并向用户显示有关文件如何损坏或密码保护的消息,并附上有关您如何不允许上传受密码保护的文件的注释。

于 2013-01-16T00:08:09.600 回答
0

以下是在 .aspx 源文件中

 Page Language="C#" AutoEventWireup="true" CodeBehind="TestForm.aspx.cs" Inherits="TestApp.TestForm"

 !DOCTYPE html PUBLIC
 Reference Page ="~/TestForm.aspx" // Note: Removed all HTML tags
    protected void Upload_Click(object sender, EventArgs e)
    {
        字符串 noPW = "C:\\Users\\David\\Desktop\\Doc1.docx";
        String pwProtected = "C:\\Users\\David\\Desktop\\Test.docx";
    // if (isProtected(pwProtected))
    // 结果.Text = ("文档受密码保护");
    // 别的
    // 结果.Text = ("文档不受密码保护");

        if (isProtected(noPW))
            结果.Text = ("文档受密码保护");
        别的
            结果.Text = ("文档不受密码保护");
    }

以下是 .aspx.cs 代码隐藏文件

    使用系统;
    使用 System.Collections.Generic;
    使用 System.Linq;
    使用 System.Web;
    使用 System.Web.UI;
    使用 System.Web.UI.WebControls;
    使用 Microsoft.Office.Interop.Word;
    使用 System.Runtime.InteropServices;
    使用 Microsoft.Office.Interop.Word;


    命名空间 TestApp
    {
        公共部分类 TestForm : System.Web.UI.Page
        {

            protected void Page_Load(object sender, EventArgs e)
            {

            }
            公共静态布尔 isProtected(对象文件路径)
            {
                应用程序 myapp = new Application();

                对象 pw = "这个密码";
                尝试
                {

                    // 对 Word 文档试试这个
                    myapp.Documents.Open(ref filePath, PasswordDocument: ref pw); // 尝试打开
                    myapp.Documents[参考文件路径].Close(); // 如果打开就关闭    
                }
                捕捉(COMException ex)
                {
                    if (ex.HResult == -2146822880) // 因密码无效而无法打开文档
                        返回真;
                    别的
                        Console.WriteLine(ex.Message + " " + ex.HResult); // 调试用,只测试过这一份文件。
                }
                返回假;
            }
        }

    }

至少在我的计算机上,我得到了两个文件的预期输出,但这并不是你所说的对代码的详尽测试。此外,我尝试使用 FileUpload 控件上传文件,但我收到 COM 错误“找不到 C:\Windows\System\fileName.docx”,这让我很困惑,因为上传的文件来自我的桌面,但是你可能知道为什么会发生这种情况,因为您比我更熟悉 ASP.NET。无论哪种方式,这段代码都是值得尝试的,希望对您有所帮助。

于 2013-01-15T23:36:55.170 回答
-1

notme一样,我不知道有一种方法可以在上传文件的一部分之前判断文件是否受密码保护,但是这个问题的公认答案虽然在技术上很好,但有点矫枉过正。

有关测试文件是否受密码保护的更简单、更快捷的方法,请参阅检测受密码保护的 word 文件。

此外,对于那些在 VBA/S 中寻找解决方案的人来说,以下是前者的版本,它很容易适应后者。www.ozgrid.com/forum/showthread.php?t=148962。尽管我建议检查 err.number = 5408 (在受保护时会使用错误的密码抛出什么),而不是使用任何 err.number 来确定该文件是否受密码保护。

于 2017-03-08T15:39:30.520 回答