pgcrypto 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -0
- data/README.markdown +19 -13
- data/VERSION +1 -1
- data/lib/pgcrypto/active_record.rb +19 -18
- data/pgcrypto.gemspec +46 -0
- metadata +3 -2
data/CHANGES
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
0.0.2
|
2
|
+
* Fixed a number of key-related bugs discovered in testing with our
|
3
|
+
second production app with encrypted columns. Also duck-typed AREL
|
4
|
+
statement types in a few places.
|
5
|
+
|
1
6
|
0.0.1
|
2
7
|
* INSERT, SELECT, and UPDATE statements are working. But I wrote this
|
3
8
|
while testing with a production app, and thus haven't written
|
data/README.markdown
CHANGED
@@ -22,9 +22,12 @@ You need to have PGCrypto installed before this guy will work. [LMGTFY](http://l
|
|
22
22
|
PGCrypto.keys[:private] = {:path => "~/.keys/private.key"}
|
23
23
|
PGCrypto.keys[:public] = {:path => "~/.keys/public.key"}
|
24
24
|
|
25
|
-
4. PGCrypto columns are named `attribute_encrypted`
|
25
|
+
4. PGCrypto columns are named `attribute_encrypted` in the binary format, so do something like this:
|
26
26
|
|
27
|
-
add_column :users, :
|
27
|
+
add_column :users, :social_security_number_encrypted, :binary
|
28
|
+
|
29
|
+
This will allow you to access `User#social_security_number` and store the user's social in an encrypted
|
30
|
+
column called `social_security_number_encryped`.
|
28
31
|
|
29
32
|
5. Tell the User class to encrypt and decrypt the `social_security_number` attribute on the fly:
|
30
33
|
|
@@ -47,14 +50,15 @@ a GPG-encrypted column that can only be decrypted with your secure key.
|
|
47
50
|
Keys
|
48
51
|
-
|
49
52
|
|
50
|
-
|
51
|
-
|
53
|
+
If you want to bundle your public key with your application, PGCrypto will automatically load `#{Rails.root}/.pgcrypto`,
|
54
|
+
so feel free to put your public key in there. You can also tell PGCrypto about your keys in a number of fun ways.
|
55
|
+
The most straightforward is to assign the actual content of the key manually:
|
52
56
|
|
53
57
|
PGCrypto.keys[:private] = "-----BEGIN PGP PRIVATE KEY BLOCK----- ..."
|
54
58
|
|
55
59
|
You can also give it more specific stuff:
|
56
60
|
|
57
|
-
PGCrypto.keys[:private] = {:path => ".private.key", :armored =>
|
61
|
+
PGCrypto.keys[:private] = {:path => ".private.key", :armored => false, :password => "myKeyPASSwhichizneededBRO"}
|
58
62
|
|
59
63
|
This is especially important if you password protect your private key files (and you SHOULD, for the record)!
|
60
64
|
|
@@ -69,8 +73,7 @@ If you do that, just tell PGCrypto which keys to use on which columns, using an
|
|
69
73
|
pgcrypto :social_security_number, :private_key => :user_private, :public_key => :user_public
|
70
74
|
end
|
71
75
|
|
72
|
-
|
73
|
-
so feel free to put your public key in there. I recommend deploy-time passing of your private key and password, to ensure it
|
76
|
+
I recommend deploy-time passing of your private key and password, to ensure it
|
74
77
|
doesn't wind up in any long-term storage on the server:
|
75
78
|
|
76
79
|
PGCrypto.keys[:private] = {:value => ENV['PRIVATE_KEY'], :password => ENV['PRIVATE_KEY_PASSWORD']}
|
@@ -78,11 +81,15 @@ doesn't wind up in any long-term storage on the server:
|
|
78
81
|
Warranty
|
79
82
|
-
|
80
83
|
|
81
|
-
As I mentioned before, this library is one HUGE hack.
|
82
|
-
|
83
|
-
|
84
|
+
As I mentioned before, this library is one HUGE hack. This is just scratching the surface of keeping your data secure.
|
85
|
+
For example, if you don't protect your log files, anyone who can read them can get your private and public keys and
|
86
|
+
decrypt whatever the hell they want. You'll also have to scrub your logs, because un-encrypted data is displayed right
|
87
|
+
alongside those private and public keys.
|
88
|
+
|
89
|
+
Basically, this will make it easy to start with asymmetric, GPG-based, column-level encryption in PostgreSQL. But that's about
|
90
|
+
it; the rest is up to you.
|
84
91
|
|
85
|
-
As such
|
92
|
+
**As such,** the author and Delightful Widgets Inc. offer ***ABSOLUTELY NO GODDAMN WARRANTY***. As I mentioned, this works great in our
|
86
93
|
Rails 3.2 world, but YMMV if your version of Arel or ActiveRecord are ahead or behind ours. Sorry, folks.
|
87
94
|
|
88
95
|
WTF NO TESTS?!!
|
@@ -91,5 +98,4 @@ WTF NO TESTS?!!
|
|
91
98
|
Nope. We built this inside of a production application, and used its test suite to debug everything. Since this is really just
|
92
99
|
a preview release, I haven't written a suite for it yet. Sorry.
|
93
100
|
|
94
|
-
|
95
|
-
Copyright (C) 2012 Delightful Widgets, Inc.
|
101
|
+
Copyright (C) 2012 Delightful Widgets, Inc. Built by Flip Sasser, Monkeypatcher Extraordinaire!
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -20,11 +20,12 @@ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
|
|
20
20
|
unless PGCrypto[table].empty?
|
21
21
|
arel.ast.columns.each_with_index do |column, i|
|
22
22
|
if options = PGCrypto[table][column.name]
|
23
|
-
key = PGCrypto.keys[options[:public_key] || :public]
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
if key = PGCrypto.keys[options[:public_key] || :public]
|
24
|
+
value = arel.ast.values.expressions[i]
|
25
|
+
quoted_value = quote_string(value)
|
26
|
+
encryption_instruction = %[pgp_pub_encrypt(#{quoted_value}, #{key.dearmored})]
|
27
|
+
arel.ast.values.expressions[i] = Arel::Nodes::SqlLiteral.new(encryption_instruction)
|
28
|
+
end
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
@@ -67,11 +68,12 @@ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
|
|
67
68
|
# Now loop through the children to encrypt them for the SELECT
|
68
69
|
where.children.each do |child|
|
69
70
|
if options = PGCrypto[child.left.relation.name]["#{child.left.name}_encrypted"]
|
70
|
-
key = PGCrypto.keys[options[:private_key] || :private]
|
71
|
-
|
72
|
-
|
71
|
+
if key = PGCrypto.keys[options[:private_key] || :private]
|
72
|
+
joins[key.name] ||= "#{key.dearmored} AS #{key.name}_key"
|
73
|
+
child.left = Arel::Nodes::SqlLiteral.new("pgp_pub_decrypt(#{child.left.name}_encrypted, keys.#{key.name}_key)")
|
74
|
+
end
|
73
75
|
end
|
74
|
-
end
|
76
|
+
end if where.respond_to?(:children)
|
75
77
|
end
|
76
78
|
end
|
77
79
|
unless joins.empty?
|
@@ -81,22 +83,21 @@ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
|
|
81
83
|
|
82
84
|
def pgcrypto_tweak_select_column(column, options, joins)
|
83
85
|
return nil unless options[:type] == :pgp
|
84
|
-
key = PGCrypto.keys[options[:private_key] || :private]
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
if key = PGCrypto.keys[options[:private_key] || :private]
|
87
|
+
select = %[pgp_pub_decrypt(#{column}, keys.#{key.name}_key#{", '#{key.password}'" if key.password}) AS "#{column.to_s.gsub(/_encrypted$/, '')}"]
|
88
|
+
joins[key.name] ||= "#{key.dearmored} AS #{key.name}_key"
|
89
|
+
Arel::Nodes::SqlLiteral.new(select)
|
90
|
+
end
|
88
91
|
end
|
89
92
|
|
90
93
|
def pgcrypto_tweak_update(arel)
|
91
94
|
# Loop through the assignments and make sure we take care of that whole
|
92
95
|
# NULL value thing!
|
93
96
|
arel.ast.values.each do |value|
|
94
|
-
if options = PGCrypto[value.left.relation.name][value.left.name]
|
95
|
-
|
96
|
-
when NilClass
|
97
|
+
if value.respond_to?(:left) && options = PGCrypto[value.left.relation.name][value.left.name]
|
98
|
+
if value.right.nil?
|
97
99
|
value.right = Arel::Nodes::SqlLiteral.new('NULL')
|
98
|
-
|
99
|
-
key = PGCrypto.keys[options[:public_key] || :public]
|
100
|
+
elsif key = PGCrypto.keys[options[:public_key] || :public]
|
100
101
|
quoted_right = quote_string(value.right)
|
101
102
|
encryption_instruction = %[pgp_pub_encrypt('#{quoted_right}', #{key.dearmored})]
|
102
103
|
value.right = Arel::Nodes::SqlLiteral.new(encryption_instruction)
|
data/pgcrypto.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "pgcrypto"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Flip Sasser"]
|
12
|
+
s.date = "2012-02-24"
|
13
|
+
s.description = "\n PGCrypto is an ActiveRecord::Base extension that allows you to asymmetrically\n encrypt PostgreSQL columns with as little trouble as possible. It's totally\n freaking rad.\n "
|
14
|
+
s.email = "flip@x451.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".rspec",
|
21
|
+
"CHANGES",
|
22
|
+
"LICENSE",
|
23
|
+
"README.markdown",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/pgcrypto.rb",
|
27
|
+
"lib/pgcrypto/active_record.rb",
|
28
|
+
"lib/pgcrypto/arel.rb",
|
29
|
+
"lib/pgcrypto/key.rb",
|
30
|
+
"lib/pgcrypto/table_manager.rb"
|
31
|
+
]
|
32
|
+
s.homepage = "http://github.com/Plinq/pgcrypto"
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = "1.8.10"
|
35
|
+
s.summary = "A transparent ActiveRecord::Base extension for encrypted columns"
|
36
|
+
|
37
|
+
if s.respond_to? :specification_version then
|
38
|
+
s.specification_version = 3
|
39
|
+
|
40
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
41
|
+
else
|
42
|
+
end
|
43
|
+
else
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgcrypto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! "\n PGCrypto is an ActiveRecord::Base extension that allows you
|
15
15
|
to asymmetrically\n encrypt PostgreSQL columns with as little trouble as possible.
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- lib/pgcrypto/arel.rb
|
33
33
|
- lib/pgcrypto/key.rb
|
34
34
|
- lib/pgcrypto/table_manager.rb
|
35
|
+
- pgcrypto.gemspec
|
35
36
|
homepage: http://github.com/Plinq/pgcrypto
|
36
37
|
licenses: []
|
37
38
|
post_install_message:
|