lib/symmetric_encryption/writer.rb in symmetric-encryption-1.0.0 vs lib/symmetric_encryption/writer.rb in symmetric-encryption-1.1.1

- old
+ new

@@ -18,23 +18,39 @@ # # options: # :compress [true|false] # Uses Zlib to compress the data before it is encrypted and # written to the file + # If true, it forces header to true. # Default: false # + # :random_key [true|false] + # Generates a new random key and iv for every new file or stream + # If true, it forces header to true. Version below then has no effect + # The Random key and iv will be written to the file/stream in encrypted + # form as part of the header + # The key and iv are both encrypted using the global key + # Default: true + # Recommended: true. Setting to false will eventually expose the + # encryption key since too much data will be encrypted using the + # same encryption key + # # :header [true|false] # Whether to include the magic header that indicates the file # is encrypted and whether its contents are compressed # # The header contains: # Version of the encryption key used to encrypt the file # Indicator if the data was compressed # Default: true # # :version - # Version of the encryption key to use when encrypting + # When random_key is true, the version of the encryption key to use + # when encrypting the header portion of the file + # + # When random_key is false, the version of the encryption key to use + # to encrypt the entire file # Default: Current primary key # # :mode # See File.open for open modes # Default: 'w' @@ -79,22 +95,26 @@ end end # Encrypt data before writing to the supplied stream def initialize(ios,options={}) - @ios = ios - header = options.fetch(:header, true) + @ios = ios + header = options.fetch(:header, true) # Compress is only used at this point for setting the flag in the header - @compress = options.fetch(:compress, false) + random_key = options.fetch(:random_key, true) + compress = options.fetch(:compress, false) + # Force header if compressed or using random iv, key pair + header = true if compress || random_key - # Use primary cipher by default, but allow a secondary cipher to be selected for encryption - @cipher = SymmetricEncryption.cipher(options[:version]) + # Create random cipher or use global primary cipher + @cipher = random_key ? SymmetricEncryption::Cipher.random_cipher : SymmetricEncryption.cipher(options[:version]) raise "Cipher with version:#{options[:version]} not found in any of the configured SymmetricEncryption ciphers" unless @cipher @stream_cipher = @cipher.send(:openssl_cipher, :encrypt) - write_header if header + # Write the Encryption header including the random iv, key, and cipher + @ios.write(@cipher.magic_header(compress, random_key, random_key, random_key)) if header end # Close the IO Stream # Flushes any unwritten data # @@ -135,23 +155,9 @@ # Does not flush internal buffers since encryption requires all data to # be written following the encryption block size # Needed by XLS gem def flush @ios.flush - end - - private - - # Write the Encryption header if this is the first write - def write_header - # Include Header and encryption version indicator - flags = @cipher.version || 0 # Same as 0b0000_0000_0000_0000 - - # If the data is to be compressed before being encrypted, set the - # compressed bit in the version byte - flags |= 0b1000_0000_0000_0000 if @compress - - @ios.write "#{MAGIC_HEADER}#{[flags].pack('v')}" end end end