Search code examples
ruby-on-rails-3character-encodingblowfish

Ruby 1.9: gem crypt19 : blowfish.encrypt_string : problem with encoding


I am building a Rails app where I serialize a hash to JSON, and then encode the hash using the gem crypt19 and the blowfish algorithm. I'm using Rails 3.0.9, Ruby 1.9.2 p180, the latest crypt19 v1.2.1 and I'm developing on Windows7. In my Rails controller, I do:

require 'crypt/blowfish'
h=Hash.new
h["thing"]="12345"
h["thang"]="abcdefghijklmnopqrstuvwxyz"

blowfish=Crypt::Blowfish.new("SECRET")

encrypted_thingy=blowfish.encrypt_string(h.to_json)

I assign encrypted_thingy to a value in the model (which is a string),

@my_model.string_thing=encrypted_thingy
@my_model.save

but when I save the model it throws an Argument Error exception where the model is saved.

invalid byte sequence in US-ASCII

(And when I assign it a plain old string, @my_model="xxxxxxxx", everything works fine.

My eventual plan is to store encrypted_thingy in the database via the model, and then later decrypt it, parse out JSON, and get the values for "thing" and "thang".

Searching the 'net suggested that I need to change the encoding, but it is not clear how I do that with the result of the crypt19/blowfish encoding.

Is there any way to store this encrypted string as a string just like any other string I store?

Or is there a way to apply some magic (along with reversible magic) to turn that funky string into a real string which I can pass around in an email?


Solution

  • I was able to make it work. There is a gem called "hex_string" which converts binary-ish things with strange encodings into byte strings.

    First I had to do

    gem install hex_string
    

    Then the code looked like this

    require 'crypt/blowfish'
    require 'hex_string'
    h=Hash.new
    h["thing"]="12345"
    h["thang"]="abcdefghijklmnopqrstuvwxyz"
    
    blowfish=Crypt::Blowfish.new("SECRET")
    
    encrypted_thingy=blowfish.encrypt_string(h.to_json).to_hex_string.split(" ").join
    

    The "encrypted_thingy" was now a string which I could pass around easily in my web app, store in a database, debug, etc without worrying about character encoding, etc.

    To reverse the process, I did this:

    decrypted_string= blowfish.decrypt_string(encrypted_thingy.to_byte_string)
    

    The decrypted string could then be JSON-parsed to extract the data in the original hash.