summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorRandy Morgan <[email protected]>2011-12-14 22:39:43 +0900
committerRandy Morgan <[email protected]>2011-12-14 22:39:43 +0900
commitbd76822d6d053d34b7348e36ee306c7aa636f143 (patch)
tree2a2b9efd5630c8dd97e379dd212a111d02c6ca2b /lib
parentb633c38b4458c2da6c552e3a20f39e4e29cc98d1 (diff)
downloadcaxlsx-bd76822d6d053d34b7348e36ee306c7aa636f143.tar.gz
caxlsx-bd76822d6d053d34b7348e36ee306c7aa636f143.zip
release prep for 1.0.14.
Diffstat (limited to 'lib')
-rw-r--r--lib/axlsx.rb2
-rw-r--r--lib/axlsx/util/ms_off_crypto.rb88
-rw-r--r--lib/axlsx/workbook/workbook.rb1
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)