1

I am automating an OpenSSL file encryption process using Ruby. The files encrypted this way need to be able to be decrypted using OpenSSL on linux command line.

I can encrypt the file using the following Ruby method:

  def encrypt_file
    cipher = OpenSSL::Cipher.new('aes-256-cbc')
    cipher.encrypt
    cipher.key = "somelongkeystring"

    buf = ""
    File.open("file.enc", "wb") do |outf|
      File.open("file.zip", "rb") do |inf|

        while inf.read(4096, buf)
          outf << cipher.update(buf)
        end
        outf << cipher.final
      end
    end
  end

I need to be able to decrypt the file (file.enc) using the following command:

$ openssl aes-256-cbc -d -in file.enc -out file.zip

However, when I run this I get an error for bad magic number after I type the key from above.

Since I cannot change the decrypt approach (meaning it uses only a password and is entered on linux command line) how can I change my Ruby method to encrypt the file so it can be decrypted this way?

6
  • Possible duplicate of stackoverflow.com/questions/14602069/… Commented Sep 2, 2015 at 7:36
  • @MarcoSandrini my question is similar to that question. however, the solution given was to change the openssl command which I stated I cannot do. I can only modify the Ruby method. Commented Sep 2, 2015 at 13:58
  • Then you should change your code so that it would use the same derivation algorithms that the command-line version of openssl uses to derivate key and IV from the passphrase. But quoting the answer of question security.stackexchange.com/questions/29106/… "uses a custom key derivation function with some repeated hashing. This is a non-standard and not-well vetted construct (!) which relies on the MD5 hash function of dubious reputation (!!);" Commented Sep 2, 2015 at 15:09
  • Given the info in the answer quoted in my previous comment, I would start thinking about alternative routes, like wrapping an invocation to the openssl command line tool into a system/exec/spawn call Commented Sep 2, 2015 at 15:12
  • @MarcoSandrini calling openssl from system or exec or open3 only accepts input from keyboard or tty. It does not accept stdin for providing the key. Commented Sep 2, 2015 at 15:22

3 Answers 3

2

With the help of a similar question in stackoverflow, Im able to achieve it in ruby.

First u've to add an iv thing into ur cipher object, like this

cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.encrypt
cipher.iv = "0"*16
cipher.key = "somelongkeystring"

While decryption u've to pass -K and -iv values

openssl aes-256-cbc -d -in file.enc -out file.zip -K <key_hex_code> -iv <iv_hex_code>

U can generate hex codes in ruby like this "string".unpack('H*'). There must be some way to generate hex codes in cli as well.

Sign up to request clarification or add additional context in comments.

Comments

1

A solution based on Sumit's answer:

require 'openssl'

class Crypto
  def initialize(key, iv, data, cipher='aes-256-cbc')
    @key = key 
    @iv = iv
    @cipher = cipher
    @data = data
  end 

  def encrypt
    c = OpenSSL::Cipher.new(@cipher).encrypt
    c.iv = @iv 
    c.key = @key
    c.update(@data) + c.final    
  end 

  def decrypt
    c = OpenSSL::Cipher.new(@cipher).decrypt
    c.iv = @iv 
    c.key = @key
    c.update(@data) + c.final    
  end 
end

iv = '0'*16
key = '1'*32
message = 'My Message' 
encrypted = Crypto.new(key,iv,message).encrypt
puts Crypto.new(key,iv,encrypted).decrypt
puts `echo -n '#{encrypted}' | openssl aes-256-cbc -d -K #{key.unpack('H*').first} -iv #{iv.unpack('H*').first}`
# My Message
# My Message

This solutions works for strings, can easily be adapted to files.

Comments

0

I got this to work though not using the Ruby OpenSSL implementation (which I would prefer). If you use the -k flag you can specify a password as the next argument then you don't need to pass anything and can use system to call it.

  system("openssl aes-256-cbc -k '#{key}' -in file.zip -out file.enc")

If anyone has an approach using the Ruby OpenSSL implementation I would appreciate it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.