The project is in a healthy, maintained state
Encrypt or decrypt OOXML spreadsheets
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.9
~> 1.4
~> 6.7

Runtime

~> 1.13
~> 3.0
 Project Readme

OOXML Encryption

License Build Status

Overview

OOXML Encryption provides encryption and decryption support for OOXML (Microsoft Excel / .xlsx files) via full-spreadsheet password protection using AES encryption with SHA-512 hashes. This is a port of the encryption part of:

Using an input OOXML file generated by https://github.com/felixbuenemann/xlsxtream, encrypted output was tested on macOS 12.5 in Microsoft Excel 16.63.1, Apple Numbers 12.1 (and QuickLook from the Finder) and LibreOffice Vanilla 7.2.5.2, all of which prompted for a password, handled an incorrect password as expected and correctly opened the decrypted spreadsheet if given the correct password.

For low-level file format details, see:

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add ooxml_encryption

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install ooxml_encryption

Usage

Encrypting a spreadsheet

If you have read a file containing an unprotected OOXML file into unprotected_data as a String using ASCII-8BIT encoding, or if you have generated such a string in memory directly, then using a password supplied as a String in an encoding of your choice:

require 'ooxml_encryption'

encryptor      = OoxmlEncryption.new
encrypted_data = encryptor.encrypt(
  unencrypted_spreadsheet_data: unprotected_data,
  password:                     password
)

...then write encrypted_data to a file using binary mode, e.g.:

File.open('/path/to/encrypted.xlsx', 'wb') do | file |
  file.write(encrypted_data)
end

Decrypting a spreadsheet

If you have read a file containing an encrypted OOXML file into encrypted_data as a String using ASCII-8BIT encoding and have obtained a password from the spreadsheet's owning user as a String in an encoding of your choice, then:

require 'ooxml_encryption'

decryptor      = OoxmlEncryption.new
decrypted_data = decryptor.decrypt(
  encrypted_spreadsheet_data: encrypted_data,
  password:                   password
)

...then write decrypted_data to a file using binary mode, e.g.:

File.open('/path/to/unprotected.xlsx', 'wb') do | file |
  file.write(decrypted_data)
end

Resource overhead

Due to the nature of the underlying file format, which has various tables written at the start of the file that can only be built once the file contents are known, encrypted spreadsheets must be created or decoded in RAM. Streamed output or input is not possible. Attempting to create or read large spreadsheets is therefore not recommended - there could be very large RAM requirements arising.

Security concerns

The level of security this provides should be assessed relative to your requirements; numerous articles are available online which discuss the pros and cons. The quality of the password will also have a big impact on the overall security of an output file.

Development

Use bundle exec rspec to run tests. Run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. If you have sufficient RubyGems access to release a new version, update the version number and date in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Locally generated RDoc HTML seems to contain a more comprehensive and inter-linked set of pages than those available from rubydoc.info. You can (re)generate the internal rdoc documentation with:

bundle exec rake rerdoc

...yes, that's rerdoc - Re-R-Doc - then open docs/rdoc/index.html.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/RIPAGlobal/ooxml_encryption.