encryptor-3.0.0/0000755000004100000410000000000012677055654013610 5ustar www-datawww-dataencryptor-3.0.0/Rakefile0000644000004100000410000000106212677055654015254 0ustar www-datawww-datarequire 'rake' require 'rake/testtask' require 'rdoc/task' require "bundler/gem_tasks" desc 'Test the encryptor gem' Rake::TestTask.new(:test) do |t| t.libs << 'lib' t.pattern = 'test/**/*_test.rb' t.verbose = true end desc 'Generate documentation for the encryptor gem' Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'Encryptor' rdoc.options << '--line-numbers' << '--inline-source' rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end desc 'Default: run unit tests.' task default: :test encryptor-3.0.0/Gemfile0000644000004100000410000000004712677055654015104 0ustar www-datawww-datasource 'https://rubygems.org' gemspec encryptor-3.0.0/MIT-LICENSE0000644000004100000410000000206212677055654015244 0ustar www-datawww-dataCopyright (c) 2011 Sean Huber - shuber@huberry.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.encryptor-3.0.0/data.tar.gz.sig0000444000004100000410000000040012677055654016421 0ustar www-datawww-dataY^dq/zóu$\;VV$ً=xMY+$?, ?ոva |Ia?6U Q)^@!q~^E:oQdƒ,npG\0UiFۿnu7Q1M"+F1&!{MՉ[t&Fa䒍ز !6nEtvgccEօ e?ßnJҵÏ&+encrypt and decrypt methods # # Defaults to { algorithm: 'aes-256-gcm', # auth_data: '', # insecure_mode: false, # hmac_iterations: 2000, # v2_gcm_iv: false } # # Run 'openssl list-cipher-commands' in your terminal to view a list all cipher algorithms that are supported on your platform def default_options @default_options ||= { algorithm: 'aes-256-gcm', auth_data: '', insecure_mode: false, hmac_iterations: 2000, v2_gcm_iv: false } end # Encrypts a :value with a specified :key and :iv. # # Optionally accepts :salt, :auth_data, :algorithm, :hmac_iterations, and :insecure_mode options. # # Example # # encrypted_value = Encryptor.encrypt(value: 'some string to encrypt', key: 'some secret key', iv: 'some unique value', salt: 'another unique value') # # or # encrypted_value = Encryptor.encrypt('some string to encrypt', key: 'some secret key', iv: 'some unique value', salt: 'another unique value') def encrypt(*args, &block) crypt :encrypt, *args, &block end # Decrypts a :value with a specified :key and :iv. # # Optionally accepts :salt, :auth_data, :algorithm, :hmac_iterations, and :insecure_mode options. # # Example # # decrypted_value = Encryptor.decrypt(value: 'some encrypted string', key: 'some secret key', iv: 'some unique value', salt: 'another unique value') # # or # decrypted_value = Encryptor.decrypt('some encrypted string', key: 'some secret key', iv: 'some unique value', salt: 'another unique value') def decrypt(*args, &block) crypt :decrypt, *args, &block end protected def crypt(cipher_method, *args) #:nodoc: options = default_options.merge(value: args.first).merge(args.last.is_a?(Hash) ? args.last : {}) raise ArgumentError.new('must specify a key') if options[:key].to_s.empty? cipher = OpenSSL::Cipher.new(options[:algorithm]) cipher.send(cipher_method) unless options[:insecure_mode] raise ArgumentError.new("key must be #{cipher.key_len} bytes or longer") if options[:key].bytesize < cipher.key_len raise ArgumentError.new('must specify an iv') if options[:iv].to_s.empty? raise ArgumentError.new("iv must be #{cipher.iv_len} bytes or longer") if options[:iv].bytesize < cipher.iv_len end if options[:iv] # This is here for backwards compatibility for Encryptor v2.0.0. cipher.iv = options[:iv] if options[:v2_gcm_iv] if options[:salt].nil? # Use a non-salted cipher. # This behaviour is retained for backwards compatibility. This mode # is not secure and new deployments should use the :salt options # wherever possible. cipher.key = options[:key] else # Use an explicit salt (which can be persisted into a database on a # per-column basis, for example). This is the preferred (and more # secure) mode of operation. cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(options[:key], options[:salt], options[:hmac_iterations], cipher.key_len) end cipher.iv = options[:iv] unless options[:v2_gcm_iv] else # This is deprecated and needs to be changed. cipher.pkcs5_keyivgen(options[:key]) end yield cipher, options if block_given? value = options[:value] if cipher.authenticated? if encryption?(cipher_method) cipher.auth_data = options[:auth_data] else value = extract_cipher_text(options[:value]) cipher.auth_tag = extract_auth_tag(options[:value]) # auth_data must be set after auth_tag has been set when decrypting # See http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-auth_data-3D cipher.auth_data = options[:auth_data] end end result = cipher.update(value) result << cipher.final result << cipher.auth_tag if cipher.authenticated? && encryption?(cipher_method) result end def encryption?(cipher_method) cipher_method == :encrypt end def extract_cipher_text(value) value[0..-17] end def extract_auth_tag(value) value[-16..-1] end end encryptor-3.0.0/lib/encryptor/0000755000004100000410000000000012677055654016403 5ustar www-datawww-dataencryptor-3.0.0/lib/encryptor/string.rb0000644000004100000410000000132412677055654020236 0ustar www-datawww-datamodule Encryptor # Adds encrypt and decrypt methods to strings module String # Returns a new string containing the encrypted version of itself def encrypt(options = {}) Encryptor.encrypt(options.merge(value: self)) end # Replaces the contents of a string with the encrypted version of itself def encrypt!(options ={}) replace encrypt(options) end # Returns a new string containing the decrypted version of itself def decrypt(options = {}) Encryptor.decrypt(options.merge(value: self)) end # Replaces the contents of a string with the decrypted version of itself def decrypt!(options = {}) replace decrypt(options) end end endencryptor-3.0.0/lib/encryptor/version.rb0000644000004100000410000000056112677055654020417 0ustar www-datawww-datamodule Encryptor # Contains information about this gem's version module Version MAJOR = 3 MINOR = 0 PATCH = 0 # Returns a version string by joining MAJOR, MINOR, and PATCH with '.' # # Example # # Version.to_s # '1.0.2' def self.to_s [MAJOR, MINOR, PATCH].join('.') end end end encryptor-3.0.0/test/0000755000004100000410000000000012677055654014567 5ustar www-datawww-dataencryptor-3.0.0/test/encryptor_string_test.rb0000644000004100000410000000601212677055654021565 0ustar www-datawww-datarequire 'test_helper' class EncryptorStringTest < Minitest::Test original_value = StringWithEncryptor.new key = SecureRandom.random_bytes(64) iv = SecureRandom.random_bytes(64) salt = Time.now.to_i.to_s original_value << SecureRandom.random_bytes(64) auth_data = SecureRandom.random_bytes(64) wrong_auth_tag = SecureRandom.random_bytes(16) OpenSSLHelper::ALGORITHMS.each do |algorithm| encrypted_value_with_iv = StringWithEncryptor.new encrypted_value_without_iv = StringWithEncryptor.new encrypted_value_with_iv << Encryptor.encrypt(value: original_value, key: key, iv: iv, salt: salt, algorithm: algorithm) encrypted_value_without_iv << Encryptor.encrypt(value: original_value, key: key, algorithm: algorithm, insecure_mode: true) define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do assert_equal encrypted_value_with_iv, original_value.encrypt(key: key, iv: iv, salt: salt, algorithm: algorithm) end define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do assert_equal encrypted_value_without_iv, original_value.encrypt(key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do assert_equal original_value, encrypted_value_with_iv.decrypt(key: key, iv: iv, salt: salt, algorithm: algorithm) end define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do assert_equal original_value, encrypted_value_without_iv.decrypt(key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do original_value_dup = original_value.dup original_value_dup.encrypt!(key: key, iv: iv, salt: salt, algorithm: algorithm) assert_equal original_value.encrypt(key: key, iv: iv, salt: salt, algorithm: algorithm), original_value_dup end define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do original_value_dup = original_value.dup original_value_dup.encrypt!(key: key, algorithm: algorithm, insecure_mode: true) assert_equal original_value.encrypt(key: key, algorithm: algorithm, insecure_mode: true), original_value_dup end define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do encrypted_value_with_iv_dup = encrypted_value_with_iv.dup encrypted_value_with_iv_dup.decrypt!(key: key, iv: iv, salt: salt, algorithm: algorithm) assert_equal original_value, encrypted_value_with_iv_dup end define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do encrypted_value_without_iv_dup = encrypted_value_without_iv.dup encrypted_value_without_iv_dup.decrypt!(key: key, algorithm: algorithm, insecure_mode: true) assert_equal original_value, encrypted_value_without_iv_dup end end end encryptor-3.0.0/test/test_helper.rb0000644000004100000410000000120712677055654017432 0ustar www-datawww-datarequire 'simplecov' require 'simplecov-rcov' require "codeclimate-test-reporter" SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::RcovFormatter, CodeClimate::TestReporter::Formatter ] SimpleCov.start do add_filter 'test' end CodeClimate::TestReporter.start require 'minitest/autorun' require 'minitest/unit' require 'digest/sha2' $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $:.unshift(File.dirname(__FILE__)) require 'encryptor' require 'openssl_helper' require 'encryptor/string' class StringWithEncryptor < String include Encryptor::String end encryptor-3.0.0/test/openssl_helper.rb0000644000004100000410000000171512677055654020142 0ustar www-datawww-datamodule OpenSSLHelper # For test debugging puts "OpenSSL Version: #{OpenSSL::OPENSSL_VERSION}" algorithms = OpenSSL::Cipher.ciphers case RUBY_PLATFORM.to_sym when :java security_class = java.lang.Class.for_name('javax.crypto.JceSecurity') restricted_field = security_class.get_declared_field('isRestricted') restricted_field.accessible = true restricted_field.set(nil, false) # if key length is less than 24 bytes: # OpenSSL::Cipher::CipherError: key length too short # if key length is 24 bytes or more: # OpenSSL::Cipher::CipherError: DES key too long - should be 8 bytes: possibly you need to install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for your JRE algorithms -= %w(des-ede3 DES-EDE3) else algorithms &= %x(openssl list-cipher-commands).split end ALGORITHMS = algorithms.freeze AUTHENTICATED_ENCRYPTION_ALGORITHMS = ['aes-128-gcm','aes-192-gcm','aes-256-gcm'] end encryptor-3.0.0/test/legacy_encryptor_string_test.rb0000644000004100000410000000571412677055654023121 0ustar www-datawww-datarequire 'test_helper' class LegacyEncryptorStringTest < Minitest::Test key = SecureRandom.random_bytes(64) iv = SecureRandom.random_bytes(64) original_value = StringWithEncryptor.new original_value << SecureRandom.random_bytes(64) OpenSSLHelper::ALGORITHMS.each do |algorithm| encrypted_value_with_iv = StringWithEncryptor.new encrypted_value_with_iv << Encryptor.encrypt(value: original_value, key: key, iv: iv, algorithm: algorithm, insecure_mode: true) encrypted_value_without_iv = StringWithEncryptor.new encrypted_value_without_iv << Encryptor.encrypt(value: original_value, key: key, algorithm: algorithm, insecure_mode: true) define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do assert_equal encrypted_value_with_iv, original_value.encrypt(key: key, iv: iv, algorithm: algorithm, insecure_mode: true) end define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do assert_equal encrypted_value_without_iv, original_value.encrypt(key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do assert_equal original_value, encrypted_value_with_iv.decrypt(key: key, iv: iv, algorithm: algorithm, insecure_mode: true) end define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do assert_equal original_value, encrypted_value_without_iv.decrypt(key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do original_value_dup = original_value.dup original_value_dup.encrypt!(key: key, iv: iv, algorithm: algorithm, insecure_mode: true) assert_equal original_value.encrypt(key: key, iv: iv, algorithm: algorithm, insecure_mode: true), original_value_dup end define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do original_value_dup = original_value.dup original_value_dup.encrypt!(key: key, algorithm: algorithm, insecure_mode: true) assert_equal original_value.encrypt(key: key, algorithm: algorithm, insecure_mode: true), original_value_dup end define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do encrypted_value_with_iv_dup = encrypted_value_with_iv.dup encrypted_value_with_iv_dup.decrypt!(key: key, iv: iv, algorithm: algorithm, insecure_mode: true) assert_equal original_value, encrypted_value_with_iv_dup end define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do encrypted_value_without_iv_dup = encrypted_value_without_iv.dup encrypted_value_without_iv_dup.decrypt!(key: key, algorithm: algorithm, insecure_mode: true) assert_equal original_value, encrypted_value_without_iv_dup end end end encryptor-3.0.0/test/encryptor_test.rb0000644000004100000410000001371512677055654020207 0ustar www-datawww-datarequire 'test_helper' # Tests for new preferred salted encryption mode # class EncryptorTest < Minitest::Test key = SecureRandom.random_bytes(32) iv = SecureRandom.random_bytes(16) iv2 = SecureRandom.random_bytes(16) salt = SecureRandom.random_bytes(16) original_value = SecureRandom.random_bytes(64) auth_data = SecureRandom.random_bytes(64) wrong_auth_tag = SecureRandom.random_bytes(16) OpenSSLHelper::ALGORITHMS.each do |algorithm| encrypted_value_with_iv = Encryptor.encrypt(value: original_value, key: key, iv: iv, salt: salt, algorithm: algorithm) encrypted_value_without_iv = Encryptor.encrypt(value: original_value, key: key, algorithm: algorithm, insecure_mode: true) define_method "test_should_crypt_with_the_#{algorithm}_algorithm_with_iv" do refute_equal original_value, encrypted_value_with_iv refute_equal encrypted_value_without_iv, encrypted_value_with_iv assert_equal original_value, Encryptor.decrypt(value: encrypted_value_with_iv, key: key, iv: iv, salt: salt, algorithm: algorithm) end define_method "test_should_crypt_with_the_#{algorithm}_algorithm_without_iv" do refute_equal original_value, encrypted_value_without_iv assert_equal original_value, Encryptor.decrypt(value: encrypted_value_without_iv, key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do assert_equal encrypted_value_with_iv, Encryptor.encrypt(original_value, key: key, iv: iv, salt: salt, algorithm: algorithm) end define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do assert_equal encrypted_value_without_iv, Encryptor.encrypt(original_value, key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do assert_equal original_value, Encryptor.decrypt(encrypted_value_with_iv, key: key, iv: iv, salt: salt, algorithm: algorithm) end define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do assert_equal original_value, Encryptor.decrypt(encrypted_value_without_iv, key: key, algorithm: algorithm, insecure_mode: true) end end define_method 'test_should_use_the_default_algorithm_if_one_is_not_specified' do assert_equal Encryptor.encrypt(value: original_value, key: key, salt: salt, iv: iv, algorithm: Encryptor.default_options[:algorithm]), Encryptor.encrypt(value: original_value, key: key, salt: salt, iv: iv) end def test_should_have_a_default_algorithm assert !Encryptor.default_options[:algorithm].nil? assert !Encryptor.default_options[:algorithm].empty? end def test_should_raise_argument_error_if_key_is_not_specified assert_raises(ArgumentError, "must specify a key") { Encryptor.encrypt('some value') } assert_raises(ArgumentError, "must specify a key") { Encryptor.decrypt('some encrypted string') } end def test_should_raise_argument_error_if_key_is_too_short assert_raises(ArgumentError, "key must be 32 bytes or longer") { Encryptor.encrypt('some value', key: '') } assert_raises(ArgumentError, "key must be 32 bytes or longer") { Encryptor.decrypt('some encrypted string', key: '') } end define_method 'test_should_raise_argument_error_if_iv_is_not_specified' do assert_raises(ArgumentError, "must specify an iv") { Encryptor.encrypt('some value', key: key) } assert_raises(ArgumentError, "must specify an iv") { Encryptor.decrypt('some encrypted string', key: key) } end define_method 'test_should_raise_argument_error_if_iv_is_too_short' do assert_raises(ArgumentError, "iv must be 16 bytes or longer") { Encryptor.encrypt('some value', key: key, iv: 'a') } assert_raises(ArgumentError, "iv must be 16 bytes or longer") { Encryptor.decrypt('some encrypted string', key: key, iv: 'a') } end define_method 'test_should_yield_block_with_cipher_and_options' do called = false Encryptor.encrypt('some value', key: key, iv: iv, salt: salt) { |cipher, options| called = true } assert called end OpenSSLHelper::AUTHENTICATED_ENCRYPTION_ALGORITHMS.each do |algorithm| define_method 'test_should_use_iv_to_initialize_encryption' do encrypted_value_iv1 = Encryptor.encrypt(value: original_value, key: key, iv: iv, salt: salt, algorithm: algorithm) encrypted_value_iv2 = Encryptor.encrypt(value: original_value, key: key, iv: iv2, salt: salt, algorithm: algorithm) refute_equal original_value, encrypted_value_iv1 refute_equal original_value, encrypted_value_iv2 refute_equal encrypted_value_iv1, encrypted_value_iv2 end define_method 'test_should_use_the_default_authentication_data_if_it_is_not_specified' do encrypted_value = Encryptor.encrypt(value: original_value, key: key, iv: iv, salt: salt, algorithm: algorithm) decrypted_value = Encryptor.decrypt(value: encrypted_value, key: key, iv: iv, salt: salt, algorithm: algorithm) refute_equal original_value, encrypted_value assert_equal original_value, decrypted_value assert_raises(OpenSSL::Cipher::CipherError) { Encryptor.decrypt(value: encrypted_value[0..-17] + wrong_auth_tag, key: key, iv: iv, salt: salt, algorithm: algorithm) } end define_method 'test_should_use_authentication_data_if_it_is_specified' do encrypted_value = Encryptor.encrypt(value: original_value, key: key, iv: iv, salt: salt, algorithm: algorithm, auth_data: auth_data) decrypted_value = Encryptor.decrypt(value: encrypted_value, key: key, iv: iv, salt: salt, algorithm: algorithm, auth_data: auth_data) refute_equal original_value, encrypted_value assert_equal original_value, decrypted_value assert_raises(OpenSSL::Cipher::CipherError) { Encryptor.decrypt(value: encrypted_value[0..-17] + wrong_auth_tag, key: key, iv: iv, salt: salt, algorithm: algorithm) } end end end encryptor-3.0.0/test/legacy_encryptor_test.rb0000644000004100000410000000652512677055654021534 0ustar www-datawww-datarequire 'test_helper' # Tests for legacy (non-salted) encryption mode # class LegacyEncryptorTest < Minitest::Test key = SecureRandom.random_bytes(64) iv = SecureRandom.random_bytes(64) original_value = SecureRandom.random_bytes(64) OpenSSLHelper::ALGORITHMS.each do |algorithm| encrypted_value_with_iv = Encryptor.encrypt(value: original_value, key: key, iv: iv, algorithm: algorithm, insecure_mode: true) encrypted_value_without_iv = Encryptor.encrypt(value: original_value, key: key, algorithm: algorithm, insecure_mode: true) define_method "test_should_crypt_with_the_#{algorithm}_algorithm_with_iv" do refute_equal original_value, encrypted_value_with_iv refute_equal encrypted_value_without_iv, encrypted_value_with_iv assert_equal original_value, Encryptor.decrypt(value: encrypted_value_with_iv, key: key, iv: iv, algorithm: algorithm, insecure_mode: true) end define_method "test_should_crypt_with_the_#{algorithm}_algorithm_without_iv" do refute_equal original_value, encrypted_value_without_iv assert_equal original_value, Encryptor.decrypt(value: encrypted_value_without_iv, key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do assert_equal encrypted_value_with_iv, Encryptor.encrypt(original_value, key: key, iv: iv, algorithm: algorithm, insecure_mode: true) end define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do assert_equal encrypted_value_without_iv, Encryptor.encrypt(original_value, key: key, algorithm: algorithm, insecure_mode: true) end define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do assert_equal original_value, Encryptor.decrypt(encrypted_value_with_iv, key: key, iv: iv, algorithm: algorithm, insecure_mode: true) end define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do assert_equal original_value, Encryptor.decrypt(encrypted_value_without_iv, key: key, algorithm: algorithm, insecure_mode: true) end end define_method 'test_should_use_the_default_algorithm_if_one_is_not_specified' do assert_equal Encryptor.encrypt(value: original_value, key: key, algorithm: Encryptor.default_options[:algorithm], insecure_mode: true), Encryptor.encrypt(value: original_value, key: key, insecure_mode: true) end def test_should_have_a_default_algorithm assert !Encryptor.default_options[:algorithm].nil? assert !Encryptor.default_options[:algorithm].empty? end def test_should_raise_argument_error_if_key_is_not_specified assert_raises(ArgumentError) { Encryptor.encrypt('some value', insecure_mode: true) } assert_raises(ArgumentError) { Encryptor.decrypt('some encrypted string', insecure_mode: true) } assert_raises(ArgumentError) { Encryptor.encrypt('some value', key: '', insecure_mode: true) } assert_raises(ArgumentError) { Encryptor.decrypt('some encrypted string', key: '', insecure_mode: true) } end def test_should_yield_block_with_cipher_and_options called = false Encryptor.encrypt('some value', key: 'some key', insecure_mode: true) { |cipher, options| called = true } assert called end end encryptor-3.0.0/test/compatibility_test.rb0000644000004100000410000000743512677055654021035 0ustar www-datawww-datarequire File.expand_path('../test_helper', __FILE__) # Test ensures that values stored by previous versions of the gem will # roundtrip and decrypt correctly in this and future versions. This is important # for data stored in databases and allows consumers of the gem to upgrade with # confidence in the future. # class CompatibilityTest < Minitest::Test ALGORITHM = 'aes-256-cbc' def self.base64_encode(value) [value].pack('m').strip end def self.base64_decode(value) value.unpack('m').first end if OpenSSL::Cipher.ciphers.include?(ALGORITHM) def test_encrypt_with_iv key = Digest::SHA256.hexdigest('my-fixed-key') iv = Digest::SHA256.hexdigest('my-fixed-iv') result = Encryptor.encrypt( algorithm: ALGORITHM, value: 'my-fixed-input', key: key, iv: iv, insecure_mode: true ) assert_equal 'nGuyGniksFXnMYj/eCxXKQ==', self.class.base64_encode(result) end def test_encrypt_without_iv key = Digest::SHA256.hexdigest('my-fixed-key') result = Encryptor.encrypt( algorithm: ALGORITHM, value: 'my-fixed-input', key: key, insecure_mode: true ) assert_equal 'XbwHRMFWqR5M80kgwRcEEg==', self.class.base64_encode(result) end def test_decrypt_with_iv key = Digest::SHA256.hexdigest('my-fixed-key') iv = Digest::SHA256.hexdigest('my-fixed-iv') result = Encryptor.decrypt( algorithm: ALGORITHM, value: self.class.base64_decode('nGuyGniksFXnMYj/eCxXKQ=='), key: key, iv: iv, insecure_mode: true ) assert_equal 'my-fixed-input', result end def test_decrypt_without_iv key = Digest::SHA256.hexdigest('my-fixed-key') result = Encryptor.decrypt( algorithm: ALGORITHM, value: self.class.base64_decode('XbwHRMFWqR5M80kgwRcEEg=='), key: key, insecure_mode: true ) assert_equal 'my-fixed-input', result end def test_encrypt_with_iv_and_salt key = Digest::SHA256.hexdigest('my-fixed-key') iv = Digest::SHA256.hexdigest('my-fixed-iv') salt = 'my-fixed-salt' result = Encryptor.encrypt( algorithm: ALGORITHM, value: 'my-fixed-input', key: key, iv: iv, salt: salt ) assert_equal 'DENuQSh9b0eW8GN3YLzLGw==', self.class.base64_encode(result) end def test_decrypt_with_iv_and_salt key = Digest::SHA256.hexdigest('my-fixed-key') iv = Digest::SHA256.hexdigest('my-fixed-iv') salt = 'my-fixed-salt' result = Encryptor.decrypt( algorithm: ALGORITHM, value: self.class.base64_decode('DENuQSh9b0eW8GN3YLzLGw=='), key: key, iv: iv, salt: salt ) assert_equal 'my-fixed-input', result end end def test_ciphertext_encrypted_with_v2_decrypts_with_v2_gcm_iv_option result = Encryptor.decrypt(@decoded_options) assert_equal @decoded_options[:plaintext], result end def test_ciphertext_encrypted_with_v2_does_not_decrypt_without_v2_gcm_iv_option assert_raises OpenSSL::Cipher::CipherError do @decoded_options.delete(:v2_gcm_iv) Encryptor.decrypt(@decoded_options) end end def setup encoded_v2_options = { plaintext: "9H/D+Sm9qMAHHsmWvEu7LGutbEspL6akB1Qb7pLtH0+YOvB9YhZxVuIpugv9\nB8PXrYFnxO+bSvspPgp4KFm4bA==\n", value: "JR44j1NhT9WOR9SH1n6xYJMcjcGagbsYtnTtGZIe+BSavKZBR8gOtgAFJSTs\nwqtIhr28O8SC7uQepdEctnclahtNf9Nh1j/Wc76Fxlb81KI=\n", key: "AquHbz6lrUKowAns+qRdwnfEupSbViADKuBMTe7DUpQ=\n", iv: "YFQ4l87YMy/qQNc10AvmtQ==\n", salt: "qy3crVknWZpYEjxr89IHUg==\n", } @decoded_options = { algorithm: 'aes-256-gcm' , v2_gcm_iv: true } encoded_v2_options.each_with_object(@decoded_options) { |(k, v), memo| memo[k] = v.unpack("m").first } end end encryptor-3.0.0/encryptor.gemspec0000644000004100000410000000343112677055654017203 0ustar www-datawww-data# -*- encoding: utf-8 -*- lib = File.expand_path('../lib/', __FILE__) $:.unshift lib unless $:.include?(lib) require 'encryptor/version' require 'date' Gem::Specification.new do |s| s.name = 'encryptor' s.version = Encryptor::Version s.date = Date.today s.platform = Gem::Platform::RUBY s.summary = 'A simple wrapper for the standard ruby OpenSSL library' s.description = 'A simple wrapper for the standard ruby OpenSSL library to encrypt and decrypt strings' s.authors = ['Sean Huber', 'S. Brent Faulkner', 'William Monk', 'Stephen Aghaulor'] s.email = ['sean@shuber.io', 'sbfaulkner@gmail.com', 'billy.monk@gmail.com', 'saghaulor@gmail.com'] s.homepage = 'http://github.com/attr-encrypted/encryptor' s.license = 'MIT' s.rdoc_options = %w(--charset=UTF-8 --inline-source --line-numbers --main README.md) s.require_paths = ['lib'] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- test/*`.split("\n") s.required_ruby_version = '>= 2.0.0' s.add_development_dependency('minitest', '>= 0') s.add_development_dependency('rake', '>= 0') s.add_development_dependency('simplecov', '>= 0') s.add_development_dependency('simplecov-rcov', '>= 0') s.add_development_dependency('codeclimate-test-reporter', '>= 0') s.requirements << 'openssl, >= v1.0.1' s.cert_chain = ['certs/saghaulor.pem'] s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/ s.post_install_message = "\n\n\nPlease be aware that Encryptor v2.0.0 had a major security bug when using AES-*-GCM algorithms.\n By default You will not be able to decrypt data that was previously encrypted using an AES-*-GCM algorithm.\n Please see the README and https://github.com/attr-encrypted/encryptor/pull/22 for more information.\n\n\n" end encryptor-3.0.0/.gitignore0000644000004100000410000000004712677055654015601 0ustar www-datawww-datapkg rdoc .bundle coverage Gemfile.lock encryptor-3.0.0/checksums.yaml.gz.sig0000444000004100000410000000040012677055654017651 0ustar www-datawww-data5 ߒVLV3agM}4F)ArD,+ii_ !/^aDnkq"ޛ.b`f*d͒'"”$[&>1 #r?/hy{_MM )X{~b @αƳp z@iڤXP!K3~˯< Tm%5YUFW 9zK$ү_\6oV4qkJN跢r= v1.0.1 will include AEAD ciphers, ie., aes-256-gcm.** #### Notes on patches/pull requests * Fork the project. * Make your feature addition or bug fix. * Add tests for it: this is important so I don't break it in a future version unintentionally. * Commit, do not mess with Rakefile, version, or history: if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull). * Send me a pull request: bonus points for topic branches. encryptor-3.0.0/checksum/0000755000004100000410000000000012677055654015412 5ustar www-datawww-dataencryptor-3.0.0/checksum/encryptor-2.0.0.gem.sha2560000644000004100000410000000010012677055654021562 0ustar www-datawww-dataf144a0dd2485a61651c302a4870b6d56d3a0da22d48ce4c1dd0630cd14527b34encryptor-3.0.0/checksum/encryptor-2.0.0.gem.sha5120000644000004100000410000000020012677055654021556 0ustar www-datawww-datac37d971669b34a0272e1e0918426ff519413a3547d100ebf972786c3faadc76348d39ac9d150186be28eae521971e6d734de93a54fe94cdc2d525eac47ec9fdd