Discuss this help topic in SecureBlackbox Forum

Decrypt document

To decrypt an OpenXML document you need to

  1. load the document into an instance of TElOfficeOpenXMLDocument class
  2. check the document format and whether the document is encrypted
  3. check the type of the encryption handler by inspecting TElOfficeOpenXMLDocument.EncryptionHandler property and checking the type of the referenced object
  4. cast the encryption handler to its real type, and set the Password property
  5. check validity of the password
  6. call TElOfficeOpenXMLDocument.DecryptTo() method to decrypt the document and save it to a stream.

C#:


void DecryptOpenXML(string sourceFilename, string destFilename, string password)
{
    using (TElOfficeDocument Document = new TElOfficeDocument())
    {
        Document.Open(sourceFilename);
        if ((Document.DocumentFormat != TSBOfficeDocumentFormat.OpenXML) && !Document.IsEncrypted)
            throw new Exception("Cannot decrypt OpenXML document");

        if (Document.EncryptionHandler is TElOfficeOpenXMLStandardEncryptionHandler)
        {
            TElOfficeOpenXMLStandardEncryptionHandler StandardEncryptionHandler = (TElOfficeOpenXMLStandardEncryptionHandler)Document.EncryptionHandler;
            StandardEncryptionHandler.Password = password;
            if (!StandardEncryptionHandler.IsPasswordValid())
                throw new Exception("Invalid password");
        }
        else
            if (Document.EncryptionHandler is TElOfficeOpenXMLAgileEncryptionHandler)
            {
                bool Found = false;
                TElOfficeOpenXMLAgileEncryptionHandler AgileHandler = (TElOfficeOpenXMLAgileEncryptionHandler)Document.EncryptionHandler;
                for (int i = 0; i < AgileHandler.KeyEncryptorCount; i++)
                {
                    if (AgileHandler.get_KeyEncryptors(i) is TElOfficeOpenXMLPasswordKeyEncryptor)
                    {
                        TElOfficeOpenXMLPasswordKeyEncryptor PasswordKeyEncryptor = (TElOfficeOpenXMLPasswordKeyEncryptor)AgileHandler.get_KeyEncryptors(i);
                        PasswordKeyEncryptor.Password = password;
                        if (PasswordKeyEncryptor.IsPasswordValid())
                        {
                            Found = true;
                            break;
                        }
                    }
                }

                if (!Found)
                    throw new Exception("Invalid password");
            }
            else
                throw new Exception("Unknown encryption handler");

        using (FileStream f = new FileStream(destFilename, FileMode.CreateNew))
        {
            Document.DecryptTo(f);
        }
    }
}
Delphi:

procedure DecryptOpenXML(const SourceFilename, DestFilename, Password : string);
var
  Document : TElOfficeDocument;
  F : TFileStream;
  AgileHandler : TElOfficeOpenXMLAgileEncryptionHandler;
  i : Integer;
  Found : Boolean;
begin
  Document := TElOfficeDocument.Create(nil);
  try
    Document.Open(SourceFilename);
    if (Document.DocumentFormat <> dfOpenXML) and not Document.IsEncrypted then
      raise Exception.Create('Cannot decrypt OpenXML document');

    if Document.EncryptionHandler is TElOfficeOpenXMLStandardEncryptionHandler then
    begin
      TElOfficeOpenXMLStandardEncryptionHandler(Document.EncryptionHandler).Password := Password;
      if not TElOfficeOpenXMLStandardEncryptionHandler(Document.EncryptionHandler).IsPasswordValid then
        raise Exception.Create('Invalid password');
    end
    else
    if Document.EncryptionHandler is TElOfficeOpenXMLAgileEncryptionHandler then
    begin
      Found := False;
      AgileHandler := TElOfficeOpenXMLAgileEncryptionHandler(Document.EncryptionHandler);
      for i := 0 to AgileHandler.KeyEncryptorCount - 1 do
        if AgileHandler.KeyEncryptors[i] is TElOfficeOpenXMLPasswordKeyEncryptor then
        begin
          TElOfficeOpenXMLPasswordKeyEncryptor(AgileHandler.KeyEncryptors[i]).Password := Password;
          if TElOfficeOpenXMLPasswordKeyEncryptor(AgileHandler.KeyEncryptors[i]).IsPasswordValid then
          begin
            Found := True;
            Break;
          end;
        end;

      if not Found then
        raise Exception.Create('Invalid password');
    end
    else
      raise Exception.Create('Unknown encryption handler');

    F := TFileStream.Create(DestFilename, fmCreate or fmShareDenyWrite);
    try
      Document.DecryptTo(F);
    finally
      FreeAndNil(F);
    end;
  finally
    FreeAndNil(Document);
  end;
end;

How To articles about MS Office OpenXML documents

Discuss this help topic in SecureBlackbox Forum