2019-08-11

23: Encrypt an Office File with Opening Password from Program

<The previous article in this series | The table of contents of this series | The next article in this series>

Encrypt any OpenDocument 'odt', 'ods', or 'odp' file or Microsoft Office 'doc', 'docx', 'xls', 'xlsx', or 'pptx' file from your program.

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Java programming language
About: C++
About: Microsoft .NET Framework
About: Python programming language
About: LibreOffice Basic
About: Apache OpenOffice Basic
About: BeanShell
About: JavaScript

The table of contents of this article


Starting Context



Target Context


  • The reader will know how to encrypt an office document file (OpenDocument 'odt', 'ods', or 'odp' file or Microsoft Office 'doc', 'docx', 'xls', 'xlsx', or 'pptx' file) with any file-opening password from his or her program, using LibreOffice or Apache OpenOffice and UNO.
Stage Direction
Here are Hypothesizer 7, Objector 23A, and Objector 23B in front of a computer.


Orientation


Hypothesizer 7
In this article, we will know how to encrypt an office document file with any file-opening password from our program.

Objector 23A
Actually, I want to store a new office document file with a password, not to set the password to an existing file.

Hypothesizer 7
Welcome, sir! This article is about storing an opened office document into a file (whether the file is existing or new) with any file-opening password; if the file is existing, the file will be first opened and then stored. This article applies also to setting any file-opening password to a conversion target file, because any file conversion is to open the converted-from file and store the document in the specified format.

Objector 23A
You say "an office document file", but what formats are in your mind?

Hypothesizer 7
I have in my mind the OpenDocument 'odt', 'ods', and 'odp' formats and the Microsoft Office 'doc', 'docx', 'xls', 'xlsx', and 'pptx' formats.

Objector 23A
You have missed the 'ppt' format . . .

Hypothesizer 7
Actually, the Microsoft 'ppt' format is not supported by the method introduced in this article, which (the way) uses LibreOffice or Apache OpenOffice and UNO.

Objector 23A
. . . Doesn't LibreOffice support the 'ppt' format?

Hypothesizer 7
It is not that LibreOffice does not support the 'ppt' format at all, but at least, it does not support setting any password to any 'ppt' format file.

In fact, we can set any password from our program to any document file for which the LibreOffice or Apache OpenOffice GUI file-saving dialog allows you to assign the password.

Objector 23A
Well, are you talking about setting any file-opening password or any password?

Hypothesizer 7
When I say "any file-opening password", it is any file-opening password; when I say "any password", it is any password including any file-editing password.

Objector 23A
So, you talk only about file-opening passwords in this article?

Hypothesizer 7
Yes.

Objector 23A
Why?

Hypothesizer 7
Because how to set any file-editing password is not so easy while setting any file-editing password does not seem so meaningful.

Objector 23A
. . . How "not so easy"?

Hypothesizer 7
We have to specify the hash of the file-editing password, not the password string, so we have to implement a logic that generates the hash.

Objector 23A
Oh. . . . Then why "not seem so meaningful"?

Hypothesizer 7
When a document is encrypted with a file-opening password, the contents of the document cannot be read with any software (or hardware), as far as the password is unknown.

Objector 23A
And?

Hypothesizer 7
When a document is equipped with a file-editing password, in fact, the protection is at the mercy of the software that is used to open the document.

Objector 23A
. . . What do you mean by "at the mercy"?

Hypothesizer 7
As the software knows the contents, it can just allow the user to edit the contents, just ignoring the file-editing password.

Objector 23A
. . .

Hypothesizer 7
For example, even if a Microsoft Word program does not allow a 'docx' document to be edited, if a third party software (for example, LibreOffice) allows the document to be edited regardless of the file-editing password, the document will be able to be edited with the third party software.

Objector 23A
Ah . . ., if the 'docx' document could be opened only by a Microsoft product, Microsoft might be able to exert the control over the document, but as a third party program that just ignores the file-editing password can open the document, the protection can be circumvented by using the third party program . . .

Objector 23B
Did you say "UNO"?

Hypothesizer 7
Yes, madam, I said so.

Objector 23B
You know, I am a newbie . . .

Hypothesizer 7
That is not any problem; you can just become a non-newbie by learning the prerequisite knowledge cited in 'Starting Context'.

Objector 23B
. . . I'm saying I am a newbie.

Hypothesizer 7
. . . Well, I think I can help a now-newbie, but I do not know what I can do for any newbie who insists on keeping being a newbie, refusing to learn.

Objector 23B
How dare you! I am a customer!

Hypothesizer 7
Any customer is not above the rules of the universe; any prerequisite knowledge does not become non-prerequisite because the reader is a customer, or even a very important customer.

Objector 23B
But that is too much!

Hypothesizer 7
What is prerequisite does not become non-prerequisite because it is too much, you know.

Objector 23B
. . . Why don't you make it gentle to any newbie?

Hypothesizer 7
. . . I do not understand what you demand. Being "gentle" does not make whatever is prerequisite non-prerequisite. . . . If you demand all the prerequisites repeated here, that will be impractical (this article will become too long before it reaches the main topic) . . .

Objector 23B
Why don't you understand?

Hypothesizer 7
Why indeed.

Objector 23B
You should explain so that anyone without any prerequisite knowledge can understand.

Hypothesizer 7
That is exorbitant. . . . That is as though demanding to be taught higher mathematics while refusing to learn elementary mathematics . . .

Objector 23B
You can just show what exactly I should do!

Hypothesizer 7
Without your understanding what you are doing or why you should do it and without your judging whether you should adopt the way? . . . That is slavery, in my opinion.

Objector 23B
. . . It's fine because I say it's fine.

Hypothesizer 7
It may be fine for you, but my being a party to slavery is not fine for me. You know, it is against my moral obligation: it is not any matter of what a slave says.

Objector 23B
So, you just want to be praised by God!

Hypothesizer 7
Actually, I am sure that there is no God whom I owe morally.

Objector 23B
. . .


Main Body


1: The Document-Storing Property to Be Set for Any OpenDocument 'odt', 'ods', or 'odp' File or Microsoft Office 'doc' or 'xls' File


Hypothesizer 7
In this article, I introduce only the document-storing properties to be set. I mean, I do not delve into how to store any document to any file using one of the document-storing properties. The previous article on converting document files (the concept, a Java implementation, a C++ implementation, a C# implementation, a Python implementation, and a LibreOffice Basic implementation) contains the necessary information.

For any OpenDocument 'odt', 'ods', or 'odp' file or Microsoft Office 'doc' or 'xls' file, we should use the property whose name is 'Password' and whose value is the file-opening password plain string.

Objector 23A
Actually, I tried to set that property for my 'docx' file, without the expected effect . . .

Hypothesizer 7
For any Microsoft 'docx' file, you have to set the property introduced in the next section.


2: The Document-Storing Property to Be Set for Any Microsoft Office 'docx', 'xlsx', or 'pptx' File


Hypothesizer 7
For any Microsoft Office 'docx', 'xlsx', or 'pptx' file, we should use the property whose name is 'EncryptionData' and whose value is a 'com.sun.star.beans.NamedValue's array (sequence for C++ and list for Python) which has a 'com.sun.star.beans.NamedValue' value whose name is 'OOXPassword' and whose value is the file-opening password plain string.

Objector 23A
Huh?

Hypothesizer 7
This is a piece of Java code that prepares the 'com.sun.star.beans.NamedValue's array.

@Java Source Code
import com.sun.star.beans.NamedValue;

			NamedValue [] l_encryptionDatumNameValuePairsArray = new NamedValue [1];
			l_encryptionDatumNameValuePairsArray [0] = new NamedValue ();
			l_encryptionDatumNameValuePairsArray [0].Name = "OOXPassword";
			l_encryptionDatumNameValuePairsArray [0].Value = "APassword";

This is a piece of C++ code that prepares the 'com.sun.star.beans.NamedValue's sequence, where '::theBiasPlanet::unoUtilities::stringsHandling::UnoExtendedStringHandler::getOustring (string const & a_utf8String)' is my utility class method that creates a UNO string instance from the specified UTF-8 '::std::string' instance (the class is in the 'unoUtilitiesToBeDisclosed' project, which is included in the ZIP file of any of my UNO samples, for example a files converter).

@C++ Source Code
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/uno/Any.h>
#include <com/sun/star/uno/Sequence.hxx>
#include "theBiasPlanet/unoUtilities/stringsHandling/UnoExtendedStringHandler.hpp"

using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::theBiasPlanet::unoUtilities::stringsHandling;

							Sequence <NamedValue> l_encryptionDatumNameValuePairsSequence (1);
							l_encryptionDatumNameValuePairsSequence [0] = NamedValue ();
							l_encryptionDatumNameValuePairsSequence [0].Name = UnoExtendedStringHandler::getOustring ("OOXPassword");
							l_encryptionDatumNameValuePairsSequence [0].Value = Any (UnoExtendedStringHandler::getOustring ("APassword"));

The C# version will not be necessary to be shown because it will be easily and correctly guessed from the Java version.

Objector 23A
Hmm, how am I supposed to know that the 'EncryptionData' property accepts such data?

Hypothesizer 7
Indeed. In fact, PGP signing data also go into that property, but I will not delve into it in this article.


3: The 2 Document-Storing Properties Should Not Be Set at the Same Time


Hypothesizer 7
In fact, I tried to set a file-opening password to a Microsoft 'xls' file setting the 2 document-storing properties at the same time, assuming that the invalid one would be just ignored.

That was not OK: a password was set, but the file could not be opened with the intended password. I did not find out what password is set instead.

So, it seems that we should not set the 2 document-storing properties at the same time.


4: The Conclusion and Beyond


Hypothesizer 7
Now, we know how to encrypt any OpenDocument 'odt', 'ods', or 'odp' file or Microsoft Office 'doc', 'docx', 'xls', 'xlsx', or 'pptx' file with any file-opening password from our program, using LibreOffice or Apache OpenOffice and UNO.

All we have to do is to set an appropriate document-storing property appropriately.

Any file that can be assigned a password in the LibreOffice or Apache OpenOffice document-storing dialog should be able to be stored with the password from our program, but the property to be set may be a different one from the 2 properties introduced in this article.

As one can see in the document-storing dialog, we can also encrypt some document files by PGP. Yes, we can do so from our program. How, we will see in a future article.

Although I have said that setting any file-editing password does not seem so meaningful, we will see how to set any file-editing password to a document in a future article (for OpenDocument formats, for the Microsoft binary Word and Excel formats, and for the Office Open XML formats).

Any PDF file password (for opening or editing) can be also set from our program, but we will see how in a future article.


References


<The previous article in this series | The table of contents of this series | The next article in this series>