Digitally Sign a Word 2002 Document and Programmatically Retrieve Digital Signature Information
Microsoft® Office XP
Summary: This article describes how to digitally sign a Microsoft Word 2002 document and programmatically retrieve digital signature information from it.
Office SignatureSet Collection
How to Digitally Sign a Document
Sign a Document Using Built-in Feature
Programmatically Sign a Document
Run the AddDigSig Macro
How to Programmatically Retrieve Document Digital Signature Details
Run the DigSigRetrieve Macro
Verify the Validity of a Signature
Digitally signing a document has many benefits. A digital signature on a file is an electronic, cryptographic-based, secure stamp of authentication. When you add a digital signature to a document, you are supplying a verifiable signature that can vouch for the authenticity and integrity of the file. The certificate used to create this signature identifies the signer. Readers of your document can be assured of the document creator's identity and that the document has not been altered since it was created.
This article will show how to sign a Microsoft Word 2002 document using Word built-in digital signing feature and programmatically using the Microsoft Office SignatureSet collection. If you want to examine the digital signature details on a signed document, you can programmatically retrieve the information, which this article will demonstrate.
To sign a document, you need a digital certificate. It is assumed that the reader knows what a digital certificate is. If not, the article What Are Digital Certificates? has more information about digital certificates. You can purchase a valid certificate for signing documents from a certification authority (CA) like VeriSign or other similar organizations.
The Office SignatureSet collection (see Figure 1) is a collection of Signature objects (see Figure 2) corresponding to the digital signatures of a document in Word 2002 and a presentation in Microsoft PowerPoint® 2002. Note that this is not implemented in Microsoft Excel 2002.
In this article, I'll focus only on Word 2002. In Word 2002, the Signature objects are contained in the Document object's SignatureSet collection. To programmatically retrieve a SignatureSet object in Word 2002, use the Document object's Signatures property.
Figure 1. The Office SignatureSet collection.
Figure 2. The Office Signature objects.
The AddDigSig.dot file included in the download accompanying this article contains sample code demonstrating how to programmatically sign a Word 2002 document. The RetrieveDigSigInfo.dot file shows you how to use the SignatureSet object in Word 2002 to programmatically retrieve digital signature information from a document.
First I'll show you how to sign a document using the Word 2002 built-in document signing feature. Then I'll show you how to do it programmatically.
- Open the document that you want to sign.
- On the Tools menu, click Options to display the Options dialog box.
- Click the Security tab.
- Click Digital Signatures button.
- In the Digital Signature dialog box, click Add. This displays the Select Certificate dialog box as shown in Figure 3.
Note If you haven't yet saved the document that you want to digitally sign, at this point you will be asked to save it. You won't be able to proceed with the signing until you've saved it.
Figure 3. Selecting a digital certificate for signing.
- Click OK to close each of the dialog boxes.
Now the document is digitally signed. How would you know? If you look at the name of the document on the top left of the document window, you will find "(Signed)" next to the document name.
Note that you can also use more than one digital certificate to sign a document. If you want to do this, repeat step 5 the same number of times as the number of digital certificates used, before continuing to step 6.
Use the SignatureSet collection's Add method to add a Signature object. Note that the Commit method must be called to persist changes to the SignatureSet collection. To remove a Signature object from a SignatureSet collection, use the Signature object's Delete method.
In the AddDigSig.dot file example, the following code snippet adds a signature to the active document.
Set sig = ActiveDocument.Signatures.Add
Note that if the document hasn't been saved yet, the user will first be asked to save it before signing. Only after it's saved that the user is prompted to select the digital certificate to be used for signing as shown in Figure 3 above.
The following code snippet checks to make sure that the digital certificate that the user selects meets certain criteria, such as it hasn't expired or been revoked, before the new signature is committed. Otherwise the signature is removed from the document.
If sig.IsCertificateExpired = False And _ sig.IsCertificateRevoked = False Then bAddSig = True Else sig.Delete bAddSig = False End If
Finally, commit the signature as shown below. Until the Commit method is executed, none of the changes to the SignatureSet collection are saved.
To run an unsigned Microsoft Visual Basic® for Applications (VBA) macro, the security settings in the Security dialog box (on the Tools menu, point to Macro, and click Security) must be set to Medium, with the Trust all installed add-ins and templates check box cleared. It is strongly recommended that you do this only in a testing environment. After you are done testing, set the security level back to High.
Caution By setting the security level to Medium, with the Trust all installed add-ins and templates check box cleared, users will have the choice to either enable or disable unsigned COM add-ins and VBA macros when they are prompted. If your security level is set to High, with the Trust all installed add-ins and templates check box cleared, all unsigned COM add-ins and VBA macros will be disabled automatically. Therefore, it is strongly recommended that all users keep their security levels set to High with the Trust all installed add-ins and templates check box cleared.
To run the AddDigSig.dot file's macro, place a copy of the AddDigSig.dot file in the following directory so that the macro will be loaded when Word opens:
Drive:\Program Files\Microsoft Office\Office10\Startup
To try out this macro, open a Word 2002 document that you want to sign. Then, on the Tools menu, point to Macro, and click Macros. This displays the Macros dialog box as shown in Figure 4 below. Select AddDigSig and click Run to sign the document. You will be prompted to select the digital certificate that you want to sign the document with.
Figure 4. Select the macro that you want to run.
The RetrieveDigSigInfo.dot file contains an example on how to programmatically retrieve document digital signature details by using the SignatureSet collection. Let's walk through the code.
If you look at the code in the
DigSigRetrieve function, the first part involves building a table, setting the font, headings, titles, and so forth to hold and display the digital signature information to be extracted. The code on how to do this is well-commented out so I won't go into it in detail. I'll concentrate on how to use the SignatureSet and Signature properties instead.
The first piece of information of interest is the number of signatures on the active document returned by the SignatureSet collection's Count property. For example, if there are two digital certificates used to sign a document, the count will be 2.
iSigCount = ActiveDocument.Signatures.Count
The code snippet below iterates through each signature present on the active document to extract the following signature property details:
- AttachCertificate property – Returns a Boolean value indicating whether the digital certificate that corresponds to the specified Signature object on the document is attached to the document.
- ExpireDate property – Returns the digital certificate expiration date.
- IsCertificateExpired property – Returns a Boolean value indicating whether the digital certificate has expired.
- IsCertificateRevoked property – Returns a Boolean value indicating whether the digital certificate has been revoked.
- Issuer property – Returns the name of the issuer of the digital certificate.
- SignDate property – Returns the date and time the document was signed.
- Signer property – Returns the name of the signer of the document.
Dim i As Integer For i = 1 To iSigCount .TypeText "Signature #" & i .MoveRight wdCell .TypeText "Is Certificate Attached?" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).AttachCertificate .MoveRight wdCell, 2 .TypeText "Expiry Date" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).ExpireDate MoveAndMerge 2 .TypeText "Is Certificate Expired?" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).IsCertificateExpired MoveAndMerge 2 .TypeText "Is Certificate Revoked?" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).IsCertificateRevoked MoveAndMerge 2 .TypeText "Is Certificate Valid?" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).IsValid MoveAndMerge 2 .TypeText "Issuer" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).Issuer MoveAndMerge 2 .TypeText "Sign Date" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).SignDate MoveAndMerge 2 .TypeText "Signer" .MoveRight wdCell .TypeText ActiveDocument.Signatures(i).Signer MoveAndMerge 1 Next
The code also has a subroutine called
MoveAndMerge to handle how the selection is moved, whether one table cell or two, to the left or right and so forth. It also has an error handling subroutine. The code is well commented and is quite easy to understand.
Before running the macro, first read the Security Settings topic above to make sure the security levels are correctly set. To run the
DigSigRetrieve macro in the RetrieveDigSigInfo.dot template, place a copy of the RetrieveDigSigInfo.dot template in the following directory so that the macro will be loaded when Word opens:
Drive:\Program Files\Microsoft Office\Office10\Startup
To try out this macro, open a Word 2002 document.
Note It is a good idea to make the document read-only so that you don't accidentally save the document, especially if it has been accidentally changed, thus invalidating the digital signature on it if there is one.
To run the macro, on the Tools menu, point to Macro, and click Macros. This displays the Macros dialog box. Select DigSigRetrieve and click Run.
If the active document isn't signed, the information extracted would look something like Figure 5. Since the document isn't signed, the Count property value is zero.
Figure 5. Document isn't signed.
If the active document is signed using one digital certificate, the signature object information extracted would look something like Figure 6. The Count property value will be 1. Since I used a test certificate to sign the document, the certificate isn't valid, therefore the value for "Is Certificate Valid" which represents the IsValid property is false.
Figure 6. Document is signed using one digital certificate.
If the active document is signed using two digital certificates, the signature object information extracted would look something like Figure 7.
Figure 7. Document is signed using two digital certificates.
One of the most useful properties in the Signature object that you could programmatically retrieve is the IsValid property. The IsValid property returns a Boolean value as to the validity of a signature on a digitally signed document. If the signature is valid, the Boolean value will be True. Otherwise, it will be False.
The DigSigValid.dot template contains a sample macro on how you can retrieve this piece of information. The following code snippet iterates through each of the signatures on a document, checking the name of the signer and verifies the validity of each of the signatures:
sSigValid = "" For Each objSignature In ActiveDocument.Signatures sSigValid = sSigValid + "Is Signature from " + _ objSignature.Signer + " Valid? " + _ Str$(objSignature.IsValid) + vbCrLf Next objSignature
Next it prints the Boolean value of the Signature object's IsValid property to a newly created document as shown by the code snippet below:
Set docNew = Documents.Add Selection.TypeText (sSigValid)
It should be noted that if a signed document has been tampered with, the IsValid property will return False even if the signed tampered document hasn't yet been saved. Therefore, to properly verify the validity of a signature on a signed document, it is a good idea to print the information onto a new document and not the active document which contains the signature. In addition, if a digital certificate used to sign the document is not valid, the signature is therefore invalid also. As such, the IsValid property will return False.
Make sure your Security Settings are correctly set before running the
DigSigValid macro. Next, place a copy of the DigSigValid.dot template in the following directory so that the macro will be loaded when Word opens:
Drive:\Program Files\Microsoft Office\Office10\Startup
To run the macro, first open a signed document. Then, on the Tools menu, point to Macro, and click Macros. This displays the Macros dialog box. Select DigSigValid and click Run.
Using the SignatureSet collection, you can programmatically add a digital signature to a document. You can also retrieve digital signature details for examination as shown in the samples. If you are interested in Office XP security and other forms of signing related to Office like code signing, the following articles have detailed information: