1
2
3
4
5
6
7
<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml" manifest:size="5451">
<manifest:encryption-data manifest:checksum-type="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#sha256-1k" manifest:checksum="sf+SmkxOGrFYbK2wexrYQaML3M3JTKcQ/KsfS2eAmHQ=">
<manifest:algorithm manifest:algorithm-name="http://www.w3.org/2001/04/xmlenc#aes256-cbc" manifest:initialisation-vector="b6PjQ7EG+uWyhk/z29dJJQ=="/>
<manifest:start-key-generation manifest:start-key-generation-name="http://www.w3.org/2000/09/xmldsig#sha256" manifest:key-size="32"/>
<manifest:key-derivation manifest:key-derivation-name="PBKDF2" manifest:key-size="32" manifest:iteration-count="100000" manifest:salt="tHaDznWSd1OYCyWzFGx1YA=="/>
</manifest:encryption-data>
</manifest:file-entry>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#!/usr/bin/perl use strict; use warnings; use File::Slurp; use Crypt::CBC; use MIME::Base64; my $xml_encr = read_file('content.xml'); my $iv = "b6PjQ7EG+uWyhk/z29dJJQ=="; $iv = decode_base64($iv); my $salt = "tHaDznWSd1OYCyWzFGx1YA=="; $salt = decode_base64($salt); #$salt = substr($salt,0,8); my $cipher = Crypt::CBC->new( -pass => 'pwd123' , -cipher => 'Cipher::AES' , -keysize => 32 , -chain_mode => 'cbc' , -pbkdf => 'pbkdf2' , -iter => 100000 #, -hasher => #, -header => 'salt' , -header => 'none' , -iv => $iv , -salt => $salt #, -padding => ); my $xml_decr = $cipher->decrypt($xml_encr); print $xml_decr;
Crypt::CBCCode (perl): (dl )1 2 3 4 5 6... # Get the salt. my $salt = $options->{salt}; my $random_salt = 1 unless defined $salt && $salt ne '1'; croak "Argument to -salt must be exactly 8 bytes long" if defined $salt && length $salt != 8 && $salt ne '1'; ...
Ciphertext does not begin with a valid header for 'salt' header mode at decrypt.pl line 34.
my $xml_decr = $cipher->decrypt($xml_encr);
my $xml_decr = $cipher->decrypt($xml_encr);
2022-02-15T21:00:01 LinuxerUnd liefert Datenmüll...
QuoteEach file entry that is encrypted shall be compressed with the “deflate” algorithm before being encrypted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#!/usr/bin/perl use strict; use warnings; ###################################################################### # Quellen (-> Kurzbezeichnungen): # Manifest-Datei innerhalb meiner .ods-Datei als zip geöffnet META-INF\manifest.xml (-> "manifest") # https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part2-packages/OpenDocument-v1.3-os-part2-packages.html (-> "oasis") # https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Encryption (-> "wp") ###################################################################### # Crypt::CBC v.3.04 gem. Vorschlag von Linuxer an zwei Stellen angepasst, damit auch 16-Byte-Salts akzeptiert werden: # Zeile 402: croak "Argument to -salt must be a multiple of 8 bytes long" if defined $salt && (length $salt) % 8 && $salt ne '1'; # Zeile 633: (length $self->{salt}) % 8 and croak "Salt must be a multiple of 8 bytes long"; use Crypt::CBC; use MIME::Base64; # Die beiden folgenden sind alternativ (s.u.): use Crypt::Digest::SHA1 qw( sha1 ); use Crypt::Digest::SHA256 qw( sha256 ); use IO::Uncompress::Inflate qw(inflate $InflateError); # Nur zu Testzwecken (s. ganz unten): use IO::Compress::Deflate qw(deflate $DeflateError); use File::Slurp; my $xml_encr = read_file('content.xml') or die $!; # manifest:initialisation-vector="b6PjQ7EG+uWyhk/z29dJJQ==" my $iv = "b6PjQ7EG+uWyhk/z29dJJQ=="; # oasis Kap. 4.16.5: "The initialization vector is a base64Binary encoded sequence." $iv = decode_base64($iv); print "IV: $iv\n"; # manifest:salt="tHaDznWSd1OYCyWzFGx1YA==" my $salt = "tHaDznWSd1OYCyWzFGx1YA=="; # oasis Kap. 4.16.12 "The salt is encoded in the attribute value as a base64Binary value." $salt = decode_base64($salt); print "Salt: $salt\n"; # Mit diesem Passwort und LibreOffice Calc v.7.1.8.1 habe ich die Datei verschlüsselt: my $pwd = 'pwd123'; # oasis Kap. 3.4.2 Abs. 1: "The start key is generated: The byte sequence representing the password in UTF-8 is used # to generate a 20-byte SHA1 digest (see [RFC3174])." #$pwd = sha1($pwd); # wp: ODF versions 1.0 and 1.1 only mandate support for the SHA-1 digest here, while version 1.2 recommends SHA-256. # manifest:start-key-generation-name="http://www.w3.org/2000/09/xmldsig#sha256" $pwd = sha256($pwd); print "PWD: $pwd\n\n"; my $cipher = Crypt::CBC->new( -pass => $pwd , -iv => $iv , -salt => $salt # wp: "ODF 1.2 ... allows ... AES (with 128, 196 or 256 bits), ... in cipher block chaining mode" # manifest:algorithm-name="http://www.w3.org/2001/04/xmlenc#aes256-cbc" , -cipher => 'Cipher::AES' , -chain_mode => 'cbc' # manifest:key-size="32" , -keysize => 32 # manifest:key-derivation-name="PBKDF2" , -pbkdf => 'pbkdf2' # oasis Kap. 3.4.2 Abs. 2: "For each file, a 16-byte salt is generated by a random generator. The salt is used together # with the start key to derive a unique 128-bit key for each file. The default iteration count # for the algorithm is 1024." #, -iter => 1024 # manifest:iteration-count="100000" , -iter => 100000 , -header => 'none' # ISO10126Padding sollte lt. einer Quelle verwendet werden, das kann hier aber nicht eingestellt werden. , -padding => 'none' #, -hasher => ); my $xml_decr = $cipher->decrypt($xml_encr); print $xml_decr; print "\n\n----------------------------------------------------------------------\n\n"; # oasis Kap. 3.4.1 "Each file entry that is encrypted shall be compressed with the “deflate” algorithm before being encrypted." my $xml_decr_inflated; inflate \$xml_decr => \$xml_decr_inflated or die "inflate failed: $InflateError\n"; print $xml_decr_inflated; __END__ # Beispiel: print "\n\n----------------------------------------------------------------------\n\n"; #my $txt = read_file('manifest.xml'); # hier nur als Beispieltext my $txt = "Foo-nder-Bar"; my ($txt_deflated, $txt_inflated); deflate \$txt => \$txt_deflated or die "deflate failed: $InflateError\n"; print $txt_deflated; print "\n\n----------------------------------------------------------------------\n\n"; my $txt_deflated_encr = $cipher->encrypt($txt_deflated); print $txt_deflated_encr; print "\n\n----------------------------------------------------------------------\n\n"; my $txt_deflated_decr = $cipher->decrypt($txt_deflated_encr); print $txt_deflated_decr; print "\n\n----------------------------------------------------------------------\n\n"; inflate \$txt_deflated_decr => \$txt_inflated or die "inflate failed: $InflateError\n"; print $txt_inflated