使用 C# 和 OpenXML 禁用 Word (Docx) 文档的复制/粘贴选项





5.00/5 (4投票s)
本文将介绍如何使用 C# 和 OpenXML 禁用 Word (Docx) 文档的复制/粘贴选项。
引言
阻止 Docx 文档的复制/粘贴是通用且最基本的需求,在此我们尝试借助 OPENXML API 来实现此功能。
再次欢迎大家阅读另一篇安全文章,您将在这里学习如何使用 OpenXML 而无需 Interop 来禁用 Microsoft Word 文档 (DOCX) 的复制/粘贴选项。
很多时候我们需要保护我们的文档,以便没有人可以编辑它或更改它,甚至无法复制粘贴其内容。为了满足此类需求,Microsoft Word 为我们提供了不同类型的锁定(保护层),例如“无更改锁定”(只读锁定)、“仅注释锁定”、“表单填写锁定”、“按节锁定”等。
要使用 Word 保护,请打开 Word 文件,在 MS Word 2007+ 中导航至“审阅”选项卡 ->“保护文档”->“限制格式设置和编辑”选项,然后选择您想要设置的任何保护级别。
在本文中,我们将了解如何锁定 Word 文档,使其内容无法被复制。让我们开始吧!
背景
在我之前的文章中,我已经解释了不同类型的 Word 文档以及如何使用 C# 和 Word Interop 对象保护 Word 文档,您可以在这里查看:这里
如果您对 OpenXMl API 有任何疑问/疑虑或想了解其介绍,例如:它是什么?为什么要使用它?从哪里下载?
您可以访问我关于 OpenXML API 的文章:这里
使用代码
要开始此应用程序,我们需要以下几项:
- Visual Studio 2008+
- C#
- OpenXML API
- Microsoft Word 2007+(非必需)
众所周知,DOCX 文档只不过是一组 XML 标签,其中 `DocumentProtection` 标签用于设置文档限制。当您解压 Word 文档时,可以在 `word\settings.xml` 文件中找到这些标签。
该标签的说明如下:
<w:documentProtection w:edit="forms" w:enforcement="1" w:cryptProviderType="rsaFull"
w:cryptAlgorithmClass="hash" w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="4"
w:cryptSpinCount="50000" w:hash="0AMSgIVdSif6F5unNC/Lk3rBvr4=" w:salt="m3sJnUyPgf0hUjz+U1Sdxg==" />
其中:
- w:edit 属性 =“forms” // 指定限制类型(在我们的例子中是“forms”锁定)
- w:enforcement=“1” // 指定是否必须强制执行文档
- w:cryptProviderType=“rsaFull” // 指示使用了哪个加密提供程序
- w:cryptAlgorithmClass=“hash” // 指示使用了哪个加密算法
- w:cryptAlgorithmType=“typeAny” // 指示算法的类型
- w:cryptAlgorithmSid=“4” // 指示带有盐值的特定哈希算法
- w:cryptSpinCount=“50000” // 哈希算法的迭代计数器
- w:hash=“0AMSgIVdSif6F5unNC/Lk3rBvr4=” // 密码哈希值
- w:salt=“m3sJnUyPgf0hUjz+U1Sdxg==” // 哈希之前的加盐密码值
请查看下面的代码片段,它将突出显示如何以编程方式将上述属性添加到 XML 中。
DocumentFormat.OpenXml.OnOffValue docProtection = new DocumentFormat.OpenXml.OnOffValue(true);
documentProtection.Enforcement = docProtection;
documentProtection.CryptographicAlgorithmClass = CryptAlgorithmClassValues.Hash;
documentProtection.CryptographicProviderType = CryptProviderValues.RsaFull;
documentProtection.CryptographicAlgorithmType = CryptAlgorithmValues.TypeAny;
documentProtection.CryptographicAlgorithmSid = 4; // SHA1
//The iteration count is unsigned
UInt32 uintVal = new UInt32();
uintVal = (uint)iterations;
documentProtection.CryptographicSpinCount = uintVal;
documentProtection.Hash = Convert.ToBase64String(generatedKey);
documentProtection.Salt = Convert.ToBase64String(arrSalt);
_objDoc.MainDocumentPart.DocumentSettingsPart.Settings.AppendChild(documentProtection);
_objDoc.MainDocumentPart.DocumentSettingsPart.Settings.Save();
_objDoc.Close();
Open XML API 具有 `DocumentProtectionValues` 枚举,它定义了文档保护值枚举。MSDN 在此处 (这里) 解释了以下枚举描述:
代码 | 描述 |
无 | 无编辑限制。将项序列化为 XML 时,其值为“none”。 |
ReadOnly | 允许无编辑。将项序列化为 XML 时,其值为“readOnly”。 |
注释 | 允许编辑注释。将项序列化为 XML 时,其值为“comments”。 |
TrackedChanges | 允许带修订跟踪的编辑。将项序列化为 XML 时,其值为“trackedChanges”。 |
表单 | 允许编辑表单字段。将项序列化为 XML 时,其值为“forms”。 |
工作原理
当我们用密码锁定任何文档时,它实际上会创建其 SALT 值,并使用 EncryptionMatrix 生成一个密钥,最后使用 `HashAlgorithm` 类通过 `ComputeHash` 方法对其进行加密。此方法将以指定的迭代次数调用,最后将结果值存储在 XML 中。
就是这样,成功保护后,用户将无法将内容复制/粘贴到 Docx 文件中或从 Docx 文件中复制/粘贴。
解锁文档
如果从 XML 中排除了上述标签,则文档将不应用任何锁定。相同的代码也适用于解锁文档,只需将 ENUM 更改为 `DocumentProtectionValues.None` 即可。
注意
- 为了阻止复制/粘贴,我们使用了表单锁定技术,但如果您使用基于表单的模板,用户可以从表单字段复制/粘贴内容。
- 要运行附加的演示代码,您需要在计算机上安装 OpenXML API。
- 附件是源代码和一个受保护的 Word 文档文件(使用示例代码保护)。
关注点
本文将不使用 Word Interop 自动化来锁定 Word 文档,因此本文不需要安装 Word。
Open XML 相对于 Interop 的优势
- Open XML 是 Word 处理文档、演示文稿和电子表格的开放标准,可以在不同平台上的多个应用程序中自由实现。
- Open XML 标准的目的是将 Microsoft Office 应用程序创建的文档解耦,以便它们可以被其他应用程序独立于专有格式进行操作,而不会丢失数据。
- 由于它轻量级,处理速度比 interop 对象快。
- 它具有良好的互操作性、向后兼容性和可编程性。
- 由于文件大小较小,它更容易管理各种文档存储,包括 Exchange 服务器、SharePoint,当然还有网络文件存储。
- 它是 IS29500 标准,免费供所有人使用,并且文档非常完善。
希望本文能帮助您保护您的工作文档,随时欢迎提出疑问和建议。
祝您保护愉快!
Prasad