views:

757

answers:

3

I need to add basic password protection to an Open XML Wordprocessing document. I can either use the COM interface, which is very slow when I have a large number of documents to process; or I can put the data directly in the docx file under <w:settings> <w:documentProtection> which is very fast. However, looking at the requirements to encrypt the password looks like it will take hours of programming. Does anyone have this algorithm already coded? I'm coding in C#.

A: 

here's a full code snippet. It gives you a command line utility to lock and unlock Word files (unlocking the file will - I think - also remove the password protection, although I did not try this).

You need OpenXML Format SDK 2.0 to run this, available here: http://www.microsoft.com/downloads/details.aspx?FamilyId=C6E744E5-36E9-45F5-8D8C-331DF206E0D0&amp;displaylang=en, and a reference to DocumentFormat.OpenXml in your project.

using System;
using System.Xml.Linq;

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

namespace LockDoc
{
    /// <summary>
    /// Manipulates modification permissions of an OpenXML document.
    /// </summary>
    class Program
    {
        /// <summary>
        /// Locks/Unlocks an OpenXML document.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: lockdoc lock|unlock filename.docx");
                return;
            }

            bool isLock = false;
            if (args[0].Equals("lock", StringComparison.OrdinalIgnoreCase))
            {
                isLock = true;
            }
            else if (!args[0].Equals("unlock", StringComparison.OrdinalIgnoreCase))
            {
                Console.Error.WriteLine("Wrong action!");
                return;
            }

            WordprocessingDocument doc = WordprocessingDocument.Open(args[1], true);
            doc.ExtendedFilePropertiesPart.Properties.DocumentSecurity =
                new DocumentFormat.OpenXml.ExtendedProperties.DocumentSecurity
                (isLock ? "8" : "0");
            doc.ExtendedFilePropertiesPart.Properties.Save();

            DocumentProtection dp =
                doc.MainDocumentPart.DocumentSettingsPart
                .Settings.ChildElements.First<DocumentProtection>();
            if (dp != null)
            {
                dp.Remove();
            }

            if (isLock)
            {
                dp = new DocumentProtection();
                dp.Edit = DocumentProtectionValues.Comments;
                dp.Enforcement = DocumentFormat.OpenXml.Wordprocessing.BooleanValues.One;

                doc.MainDocumentPart.DocumentSettingsPart.Settings.AppendChild(dp);
            }

            doc.MainDocumentPart.DocumentSettingsPart.Settings.Save();

            doc.Close();
        }
    }
}
Brij
Hi Brij,thanks for the code. I already had something similar and was hoping to get the algorithm for the password hash. I subsequently found some incomplete code on the MSDN forum, and also discovered that the Word 2007 password protection is very easily got around. So for now I'm just putting a random hash and salt in so no one, including me, knows the actual password. That's enough effort to prevent accidental changing; and given it's impossible to prevent intentional changing, I'm not going to make it any more secure. Thanks anyway.
axeman
A: 

is this code also support for word doc 97-2003, i have to requiremt to convert docx to doc and then password protection, but if i open file from this code doc 2003 , showing corrupted file

ashok
A: 

You can use Aspose.Words for .NET. You will be able to open DOC, DOCX, RTF or WordML protected or not, then protect or unprotect and save as DOC, DOCX, RTF or WordML 2003.

Related info: http://www.aspose.com/documentation/.net-components/aspose.words-for-.net-and-java/aspose.words.document.protect_overloads.html http://www.aspose.com/documentation/.net-components/aspose.words-for-.net-and-java/aspose.words.settings.writeprotection.html

romeok