diff options
| author | Randy Morgan <[email protected]> | 2011-12-14 22:39:43 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2011-12-14 22:39:43 +0900 |
| commit | bd76822d6d053d34b7348e36ee306c7aa636f143 (patch) | |
| tree | 2a2b9efd5630c8dd97e379dd212a111d02c6ca2b /lib | |
| parent | b633c38b4458c2da6c552e3a20f39e4e29cc98d1 (diff) | |
| download | caxlsx-bd76822d6d053d34b7348e36ee306c7aa636f143.tar.gz caxlsx-bd76822d6d053d34b7348e36ee306c7aa636f143.zip | |
release prep for 1.0.14.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/axlsx.rb | 2 | ||||
| -rw-r--r-- | lib/axlsx/util/ms_off_crypto.rb | 88 | ||||
| -rw-r--r-- | lib/axlsx/workbook/workbook.rb | 1 |
3 files changed, 91 insertions, 0 deletions
diff --git a/lib/axlsx.rb b/lib/axlsx.rb index daa7ea11..2f347d49 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -7,6 +7,8 @@ require 'axlsx/util/simple_typed_list.rb' require 'axlsx/util/constants.rb' require 'axlsx/util/validators.rb' +require 'axlsx/util/ms_off_crypto.rb' + # to be included with parsable intitites. #require 'axlsx/util/parser.rb' diff --git a/lib/axlsx/util/ms_off_crypto.rb b/lib/axlsx/util/ms_off_crypto.rb new file mode 100644 index 00000000..7f20ac28 --- /dev/null +++ b/lib/axlsx/util/ms_off_crypto.rb @@ -0,0 +1,88 @@ +require 'digest' +require 'base64' +require 'openssl' +module Axlsx + class MsOffCrypto + + attr_reader :verifier + attr_reader :key + + def initialize(password = "passowrd") + @password = password + @salt_size = 0x10 + @key_size = 0x100 + @verifier = rand(16**16).to_s + + #fixed salt for testing + @salt = [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D].join + # @salt =Digest::SHA1.digest(rand(16**16).to_s) + end + + def encryption_info + # v.major v.minor flags header length flags size # AES 128 bit + header = [3, 0, 2, 0, 0x24, 0, 0, 0, 0xA4, 0, 0, 0, 0x24, 0, 0, 0, 0, 0, 0, 0, 0x0E, 0x66, 0, 0] + header.concat [0x04, 0x80, 0, 0, 0x80, 0, 0, 0, 0x18, 0, 0, 0, 0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0] + header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a + header.concat [0, 0] + header.concat [0x10, 0, 0, 0] + header.concat [0x90,0xAC,0x68,0x0E,0x76,0xF9,0x43,0x2B,0x8D,0x13,0xB7,0x1D,0xB7,0xC0,0xFC,0x0D] + header.concat encrypted_verifier.bytes.to_a.pack('c*').bytes.to_a + header.concat [20, 0,0,0] + header.concat encrypted_verifier_hash.bytes.to_a.pack('c*').bytes.to_a + header.flatten! + header.pack('c*') + end + + def encryption_verifier + {:salt_size => @salt_size, + :salt => @salt, + :encrypted_verifier => encrypted_verifier, + :varifier_hash_size => 0x14, + :encrypted_verifier_hash => encrypted_verifier_hash} + end + + # 2.3.3 + def encrypted_verifier + @encrypted_verifier ||= encrypt(@verifier) + end + + # 2.3.3 + def encrypted_verifier_hash + verifier_hash = Digest::SHA1.digest(@verifier) + verifier_hash << Array.new(32 - verifier_hash.size, 0).join('') + @encrypted_verifier_hash ||= encrypt(verifier_hash) + end + + # 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption) + def key + sha = Digest::SHA1.new() << (@salt + @password) + (0..49999).each { |i| sha.update(i.to_s+sha.to_s) } + key = sha.update(sha.to_s+'0').digest + a = key.bytes.each_with_index.map { |item, i| 0x36 ^ item } + x1 = Digest::SHA1.digest((a.concat Array.new(64 - key.size, 0x36)).to_s) + a = key.bytes.each_with_index.map { |item, i| 0x5C ^ item } + x2 = Digest::SHA1.digest( (a.concat Array.new(64 - key.size, 0x5C) ).to_s) + x3 = x1 + x2 + @key ||= x3.bytes.to_a[(0..31)].pack('c*') + end + + def verify_password + puts decrypt(@encrypted_verifier) + end + + def encrypt(data) + aes = OpenSSL::Cipher.new("AES-128-ECB") + aes.encrypt + aes.key = key + aes.update(data) + end + + def decrypt(data) + aes = OpenSSL::Cipher.new("AES-128-ECB") + aes.decrypt + aes.key = key + aes.update(data) + end + + end +end diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index 4d55ad1e..60468870 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -147,6 +147,7 @@ require 'axlsx/workbook/worksheet/worksheet.rb' builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml| xml.workbook(:xmlns => XML_NS, :'xmlns:r' => XML_NS_R) { xml.workbookPr(:date1904=>@@date1904) + #<x:workbookProtection workbookPassword="xsd:hexBinary data" lockStructure="1" lockWindows="1" /> xml.sheets { @worksheets.each_with_index do |sheet, index| xml.sheet(:name=>sheet.name, :sheetId=>index+1, :"r:id"=>sheet.rId) |
