1

problem when trying to create encrypted column. OS X 10.9.5

Created public/private keys with gnupg 2.0.22:

    gpg -a --export > myKey .key.pub
    gpg -a --export-secret-key myKey > .key.prv

Any pointers on what might be going on here? I've got a model with a ssn field migration added as:

    add_column :users, :ssn, :binary

In user model

    has_encrypted_column :ssn

added pgcrpyto extension to development database

In config/initializers/pgcrypto.rb

    PGCrypto.keys[.public] = {path: '.key.pub'}
    PGCrypto.keys[.private] = {path: '.key.prv',armored: true, password: 'myPassword'}

rails c

    User.create(username:'x',ssn:'123-45-6789')

Get this error, column is ssn so it looks like it is doing the right thing

TypeError: wrong argument type Arel::Nodes::BindParam (expected String)
from ... /vendor/ruby/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql/quoting.rb:19:in `escape_string'
from ... /vendor/ruby/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql/quoting.rb:19:in `quote_string'
from ... /vendor/ruby/2.2.0/gems/pgcrypto-0.4.1/lib/pgcrypto/adapter.rb:51:in `pgcrypto_encrypt_string'

The following **** is where I assume the bug is but not sure what method to call here: Can't find much documentation about Arel::Nodes::BindParam. I assume this should set value to '123-45-6789', then encrypt it with pgcrypto_encrypt_string call. I verified that the key is correct.

     57     def pgcrypto_insert(arel)
     58       if table = PGCrypto[arel.ast.relation.name.to_s]
     59         arel.ast.columns.each_with_index do |column, i|
     60           if options = table[column.name.to_sym]
     61             key = options[:key] || PGCrypto.keys[:public]
     62             next unless key
     63             # Encrypt encryptable columns
     64   *****     value = arel.ast.values.expressions[i]
     65             arel.ast.values.expressions[i] = pgcrypto_encrypt_string(value, key)
     66           end
     67         end
     68      end
     69    end

Any pointers greatly appreciated. Happy to fork and do a pull request when figured out.

user764389
  • 51
  • 1
  • 7
  • I'm currently working on attacking this exact issue. As you surmised below, it is indeed due to the changes introduced with Rails 4.2 and Arel 6.0. The fix is nontrivial but I plan to submit it as a PR to the pgcrypto gem. I'll let you know when I get it working! – Jazz Jul 08 '15 at 23:12
  • You can find a fork of the pgcrypto gem that works with Rails 4.2 at https://github.com/BlinkerGit/pgcrypto. It also adds support for symmetric encryption (set `PGCrypto.mode = :symmetric` and `PGCrypto.keys[:symmetric] = 'your_key'` in the initializer file). I modified the gem pretty heavily and I'm sure I haven't covered all edge cases, so please **consider this fork experimental** and let me know if you see any errors or abnormal behavior. Thanks! – Jazz Jul 13 '15 at 23:32

1 Answers1

1

Guessing it is due to Arel 6.0 in Rails 4.2.0

In rails 4.1.0, Arel 5.0

    Arel::Nodes::BindParams < Arel::Nodes::SqlLiteral < String < Object < BasicObject

In rails 4.2.0 Arel 6.0

    Arel::Nodes::BindParams < Arel::Nodes::Node < Object < BasicObject

Any tips on how to pull a value from Arel::Nodes::Node

user764389
  • 51
  • 1
  • 7