Skip to content

Cannot open password protected SHA1 encrypted files. #68

@feinorgh

Description

@feinorgh

I've been trying to get this module to work with XLSX files produced by Excel 14.0.7166.5000 (32-bit) (from the Microsoft Office Professional Plus 2010 package).

I tried to see what happened through the module, and realized the first problem is that it interprets the hashing algorithm as SHA1 (not SHA-1).

diff --git a/lib/Spreadsheet/ParseXLSX/Decryptor.pm b/lib/Spreadsheet/ParseXLSX/
Decryptor.pm
index 4968a7d..3a84e15 100644
--- a/lib/Spreadsheet/ParseXLSX/Decryptor.pm
+++ b/lib/Spreadsheet/ParseXLSX/Decryptor.pm
@@ -93,6 +93,8 @@ sub _standardDecryption {

     my ($cipherAlgorithm, $hashAlgorithm);

+    print "\$algID: $algID, \$algIDHash: $algIDHash\n";
+
     if ($algID == 0x0000660E || $algID == 0x0000660F || $algID == 0x0000660E) {
         $cipherAlgorithm = 'AES';
     } else {
@@ -194,7 +196,7 @@ sub new {

     if ($self->{hashAlgorithm} eq 'SHA512') {
         $self->{hashProc} = \&Digest::SHA::sha512;
-    } elsif ($self->{hashAlgorithm} eq 'SHA-1') {
+    } elsif ($self->{hashAlgorithm} eq 'SHA-1' || $self->{hashAlgorithm} eq 'SHA1') {
         $self->{hashProc} = \&Digest::SHA::sha1;
     } elsif ($self->{hashAlgorithm} eq 'SHA256') {
         $self->{hashProc} = \&Digest::SHA::sha256;

So after this, I got a new error, namely that the wrong password was given. So I compared the produced hashes and realized they are similar, but possibly with the wrong bit size, since the hash is zero padded when unpacked:

diff --git a/lib/Spreadsheet/ParseXLSX/Decryptor/Agile.pm b/lib/Spreadsheet/ParseXLSX/Decryptor/Agile.pm
index 0405a68..902c368 100644
--- a/lib/Spreadsheet/ParseXLSX/Decryptor/Agile.pm
+++ b/lib/Spreadsheet/ParseXLSX/Decryptor/Agile.pm
@@ -94,6 +94,11 @@ sub verifyPassword {
     my $encryptedVerifierHash0 = $self->{hashProc}->($self->decrypt($encryptedVerifier, "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79"));
     $encryptedVerifierHash = $self->decrypt($encryptedVerifierHash, "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e");

+    use Data::Dump;
+    dd($encryptedVerifierHash0);
+    dd($encryptedVerifierHash);
+    print "'$encryptedVerifierHash0'\n";
+    print "'$encryptedVerifierHash'\n";
     die "Wrong password: $self" unless ($encryptedVerifierHash0 eq $encryptedVerifierHash);
 }

pack("H*","053129c83b159a03a74b824a5cfe1ed4690a52fe")
pack("H*","053129c83b159a03a74b824a5cfe1ed4690a52fe000000000000000000000000")
'1)▒;▒▒K▒J\▒▒i
R▒'
'1)▒;▒▒K▒J\▒▒i
R▒'

So they "look" similar produced as strings but do not compare to the same value (I suppose). I could not dig deeper into the issue currently, unfortunately, but there might be an easy fix. My knowledge of hashes and encryption routines is however limited, but it might be obvious to someone else.

Attached is the example Excel file protected by the password "foobar".

sha1-password-protected.xlsx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions