attr_keyring 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: caf27704434485775f0d328115de5a7803784efea398278d2ab091f90812fe69
4
- data.tar.gz: 52ee0ed25266480a59444793108e5839d5c09064f50f8280bfe5a056ce827046
3
+ metadata.gz: 040617a8065c7ec13a8c56b5bbe03e0caae106f49b6bd4942069e0cce74de3f7
4
+ data.tar.gz: 220bc96f6beec989d76dc6e2371eef0321924c6c829cb70898f19adf36fd42a6
5
5
  SHA512:
6
- metadata.gz: 6eb5b417fdb67fd63d72d7cb263f26269192658d8b92b498a168163321cd5be68734244494161755911082b509f6cd16b340d253d8b88208b0586831a7c471de
7
- data.tar.gz: 68bb5d48c931766027d4e6541044263f16c117d3628577a0a9bf79bddeace82dc25773d8d8b0b387ab24a39c7a58f01e94a6376a74740f0b5f53faaf01e7832d
6
+ metadata.gz: 2288a6fa22598c54ef3d6529ed3a85a8d3b0f755e06ab914cf5cf1e40fb4cf8bc543001f950626183e834e01d9dbed540c9213174567a4bebda3195e617cabad
7
+ data.tar.gz: a5d942f7b7ea4ed2310267340262cc6fed0057b809602e4a0a4f92f07914a4a0cbc88a8c6b3dc09860eae19cb6b5e0aa36fe655a9be9f8e049a36e2e120e1242
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attr_keyring (0.1.1)
4
+ attr_keyring (0.2.0)
5
5
  activerecord
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
- # attr_keyring
1
+ ![attr_keyring: Simple encryption-at-rest with key rotation support for ActiveRecord.](https://raw.githubusercontent.com/fnando/attr_keyring/master/attr_keyring.png)
2
2
 
3
- [![Travis-CI](https://travis-ci.org/fnando/attr_keyring.svg)](https://travis-ci.org/fnando/attr_keyring)
4
- [![Code Climate](https://codeclimate.com/github/fnando/attr_keyring/badges/gpa.svg)](https://codeclimate.com/github/fnando/attr_keyring)
5
- [![Test Coverage](https://codeclimate.com/github/fnando/attr_keyring/badges/coverage.svg)](https://codeclimate.com/github/fnando/attr_keyring/coverage)
6
- [![Gem](https://img.shields.io/gem/v/attr_keyring.svg)](https://rubygems.org/gems/attr_keyring)
7
- [![Gem](https://img.shields.io/gem/dt/attr_keyring.svg)](https://rubygems.org/gems/attr_keyring)
8
-
9
- Simple encryption-at-rest with key rotation support for ActiveRecord.
3
+ <p align="center">
4
+ <a href="https://travis-ci.org/fnando/attr_keyring"><img src="https://travis-ci.org/fnando/attr_keyring.svg" alt="Travis-CI"></a>
5
+ <a href="https://codeclimate.com/github/fnando/attr_keyring"><img src="https://codeclimate.com/github/fnando/attr_keyring/badges/gpa.svg" alt="Code Climate"></a>
6
+ <a href="https://codeclimate.com/github/fnando/attr_keyring/coverage"><img src="https://codeclimate.com/github/fnando/attr_keyring/badges/coverage.svg" alt="Test Coverage"></a>
7
+ <a href="https://rubygems.org/gems/attr_keyring"><img src="https://img.shields.io/gem/v/attr_keyring.svg" alt="Gem"></a>
8
+ <a href="https://rubygems.org/gems/attr_keyring"><img src="https://img.shields.io/gem/dt/attr_keyring.svg" alt="Gem"></a>
9
+ </p>
10
10
 
11
11
  N.B.: attr_keyring is *not* for encrypting passwords--for that, you should use something like [bcrypt](https://github.com/codahale/bcrypt-ruby). It's meant for encrypting sensitive data you will need to access in plain text (e.g. storing OAuth token from users). Passwords do not fall in that category.
12
12
 
@@ -30,9 +30,75 @@ Or install it yourself as:
30
30
 
31
31
  ## Usage
32
32
 
33
+ ### Model Configuration
34
+
35
+ #### Migration
36
+
37
+ 1. You'll need a column to track the key that was used for encryption; by default it's called `keyring_id`.
38
+ 2. Every encrypted columns must follow the name `encrypted_<column name>`.
39
+ 3. Optionally, you can also have a `<column name>_digest` to help with searching (see Lookup section below).
40
+
41
+ The following example shows how to create a column `twitter_oauth_token` without the digest, and another one called `social_security_number` with the digest column.
42
+
43
+ ```ruby
44
+ class CreateUsers < ActiveRecord::Migration[5.2]
45
+ def change
46
+ create_table :users do |t|
47
+ t.citext :email, null: false
48
+ t.timestamps
49
+
50
+ # The following columns are used for encryption.
51
+ t.binary :encrypted_twitter_oauth_token
52
+ t.binary :encrypted_social_security_number
53
+ t.text :social_security_number_digest
54
+ t.integer :keyring_id
55
+ end
56
+
57
+ add_index :users, :email, unique: true
58
+ add_index :users, :social_security_number_digest, unique: true
59
+ end
60
+ end
61
+ ```
62
+
63
+ #### ActiveRecord
64
+
65
+ ```ruby
66
+ class ApplicationRecord < ActiveRecord::Base
67
+ self.abstract_class = true
68
+
69
+ include AttrKeyring
70
+ end
71
+
72
+ class User < ApplicationRecord
73
+ attr_keyring ENV["USER_KEYRING"]
74
+ attr_encrypt :twitter_oauth_token, :social_security_number
75
+ end
76
+ ```
77
+
78
+ The code above will encrypt your columns with the current key. If you're updating a record, then the column will be migrated to the latest key available.
79
+
80
+ You can use the model as you would normally do.
81
+
82
+ ```ruby
83
+ user = User.create(
84
+ email: "john@example.com",
85
+ twitter_oauth_token: "TOKEN",
86
+ social_security_number: "SSN"
87
+ )
88
+
89
+ user.twitter_oauth_token
90
+ #=> TOKEN
91
+
92
+ user.keyring_id
93
+ #=> 1
94
+
95
+ user.encrypted_twitter_oauth_token
96
+ #=> "\xF0\xFD\xE3\x98\x98\xBBBp\xCCV45\x17\xA8\xF2r\x99\xC8W\xB2i\xD0;\xC2>7[\xF0R\xAC\x00s\x8F\x82QW{\x0F\x01\x88\x86\x03w\x0E\xCBJ\xC6q"
97
+ ```
98
+
33
99
  ### Encryption
34
100
 
35
- The key should be 16 bytes of random data, base64-encoded. A simple way to generate that is:
101
+ By default, AES-128-CBC is the algorithm used for encryption. This algorithm uses 16 bytes keys. Using 16-bytes of random data base64-encoded is the recommended way. You can easily generate keys by using the following command:
36
102
 
37
103
  ```console
38
104
  $ dd if=/dev/urandom bs=16 count=1 2>/dev/null | openssl base64
@@ -40,14 +106,29 @@ $ dd if=/dev/urandom bs=16 count=1 2>/dev/null | openssl base64
40
106
 
41
107
  Include the result of this in the `value` section of the key description in the keyring.
42
108
 
109
+ You can also use AES-256-CBC, which uses 32-bytes keys. To specify the encryptor when defining the keyring, use `encryptor: AttrKeyring::Encryptor::AES256CBC`.
110
+
111
+ ```ruby
112
+ class User < ApplicationRecord
113
+ attr_keyring ENV["USER_KEYRING"],
114
+ encryptor: AttrKeyring::Encryptor::AES256CBC
115
+ end
116
+ ```
117
+
118
+ To generate keys, use `bs=32` instead.
119
+
120
+ ```console
121
+ $ dd if=/dev/urandom bs=32 count=1 2>/dev/null | openssl base64
122
+ ```
123
+
43
124
  ### Keyring
44
125
 
45
126
  Keys are managed through a keyring--a short JSON document describing your encryption keys. The keyring must be a JSON object mapping numeric ids of the keys to the key values. A keyring must have at least one key. For example:
46
127
 
47
128
  ```json
48
129
  {
49
- "1": "PV8+EHgJlHfsVVVstJHgEo+3OCSn4iJDzqJs55U650Q=",
50
- "2": "0HyJ15am4haRsCyiFCxDdlKwl3G5yPNKTUbadpaIfPI="
130
+ "1": "QSXyoiRDPoJmfkJUZ4hJeQ==",
131
+ "2": "r6AfOeilPDJomFsiOXLdfQ=="
51
132
  }
52
133
  ```
53
134
 
@@ -59,8 +140,8 @@ If you're using Rails 5.2+, you can use credentials to define your keyring. Your
59
140
 
60
141
  ```yaml
61
142
  user_keyring:
62
- 1: "PV8+EHgJlHfsVVVstJHgEo+3OCSn4iJDzqJs55U650Q="
63
- 2: "0HyJ15am4haRsCyiFCxDdlKwl3G5yPNKTUbadpaIfPI="
143
+ 1: "QSXyoiRDPoJmfkJUZ4hJeQ=="
144
+ 2: "r6AfOeilPDJomFsiOXLdfQ=="
64
145
  ```
65
146
 
66
147
  Then you can setup your model by using `attr_keyring Rails.application.credentials.user_keyring`.
@@ -70,23 +151,6 @@ Other possibilities (e.g. the keyring file is provided by configuration manageme
70
151
  - `attr_keyring YAML.load_file(keyring_file)`
71
152
  - `attr_keyring JSON.parse(File.read(keyring_file))`.
72
153
 
73
- ### Model Setup
74
-
75
- ```ruby
76
- class ApplicationRecord < ActiveRecord::Base
77
- self.abstract_class = true
78
-
79
- include AttrKeyring
80
- end
81
-
82
- class User < ApplicationRecord
83
- attr_keyring ENV["APP_KEYRING"]
84
- attr_encrypt :twitter_oauth_token
85
- end
86
- ```
87
-
88
- The code above will encrypt your columns with the current key. If you're updating a record, then the column will be migrated to the latest key available.
89
-
90
154
  ### Lookup
91
155
 
92
156
  One tricky aspect of encryption is looking up records by known secret. E.g.,
@@ -97,7 +161,7 @@ User.where(twitter_oauth_token: "241F596D-79FF-4C08-921A-A19E533B4F52")
97
161
 
98
162
  is trivial with plain text fields, but impossible with the model defined as above.
99
163
 
100
- If add a column `<attribute>_digest`, a SHA256 value will be saved, allowing you to lookup by that value instead.
164
+ If add a column `<attribute>_digest` exists, then a SHA256 digest from the value will be saved. This will allow you to lookup by that value instead and add unique indexes.
101
165
 
102
166
  ```ruby
103
167
  User.where(twitter_oauth_token_digest: Digest::SHA256.hexdigest("241F596D-79FF-4C08-921A-A19E533B4F52"))
@@ -110,12 +174,11 @@ Because attr_keyring uses a keyring, with access to multiple keys at once, key r
110
174
  To check if an existing key with id `123` is still in use, run:
111
175
 
112
176
  ```ruby
177
+ # For a large dataset, you may want to index the `keyring_id` column.
113
178
  User.where(keyring_id: 123).empty?
114
179
  ```
115
180
 
116
- For a large dataset, you may want to index the `keyring_id` column.
117
-
118
- You may not want wait for records to be updated (e.g. key leaking). In that case, you can manually run something like the following:
181
+ You may not want to wait for records to be updated (e.g. key leaking). In that case, you can rollout a key rotation:
119
182
 
120
183
  ```ruby
121
184
  User.where(keyring_id: 1234).find_each do |user|
@@ -137,6 +200,10 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/fnando
137
200
 
138
201
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
139
202
 
203
+ ## Icon
204
+
205
+ Icon made by [Icongeek26](https://www.flaticon.com/authors/icongeek26) from [Flaticon](https://www.flaticon.com/) is licensed by Creative Commons BY 3.0.
206
+
140
207
  ## Code of Conduct
141
208
 
142
- Everyone interacting in the AttrKeyring project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/fnando/attr_keyring/blob/master/CODE_OF_CONDUCT.md).
209
+ Everyone interacting in the attr_keyring project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/fnando/attr_keyring/blob/master/CODE_OF_CONDUCT.md).
data/attr_keyring.png ADDED
Binary file
data/attr_keyring.svg ADDED
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <g transform="translate(184 95)">
4
+ <path fill="#E48E66" fill-rule="nonzero" d="M313.972078,203.445617 C287.364275,195.224256 258.801312,208.151943 247.415819,233.588161 C236.030325,259.017026 245.401859,288.946312 269.260678,303.337372 C293.11215,317.721081 323.946329,312.036721 341.109098,290.093479 C358.271866,268.142884 356.360809,236.838468 336.669564,217.138084 C330.326322,210.791898 322.542436,206.092925 313.972078,203.445617 Z M312.560836,125.188253 C383.490478,124.019025 445.305843,173.281015 460.006287,242.714021 C474.706731,312.139672 438.176129,382.256566 372.869406,409.957701 C307.562685,437.658838 231.789248,415.178782 192.1348,356.335008 C152.480353,297.491235 160.065782,218.785297 210.223696,168.604104 C237.382766,141.35154 274.104475,125.776544 312.560836,125.188253 Z"/>
5
+ <path fill="#D18162" d="M313.972078,203.445617 C314.097032,203.48974 314.214635,203.533863 314.332239,203.570631 L314.332239,125.202959 C313.744221,125.202959 313.156203,125.1809 312.560836,125.188253 C231.326183,126.504554 166.29877,193.018166 166.783885,274.30523 C167.268999,355.584938 233.090237,421.319066 314.332239,421.664686 L314.332239,308.690817 C291.715607,315.853257 267.048262,307.727492 253.112241,288.519802 C239.168871,269.312112 239.080668,243.339079 252.891735,224.035791 C266.702801,204.732504 291.311344,196.444959 313.972078,203.452973 L313.972078,203.445617 Z"/>
6
+ <path fill="#F8EC7D" d="M617.036428,535.66071 L617.374537,606.329125 L617.315735,606.821819 L559.623844,607.513061 L552.398575,570.921382 L509.216023,556.949477 L500.579512,519.019437 L457.022096,505.371094 L450.715607,462.447937 L390.8407,402.545239 L390.105676,401.265708 C409.142751,390.022003 425.445543,374.697029 437.845368,356.386483 L617.036428,535.66071 Z"/>
7
+ <path fill="#63316D" fill-rule="nonzero" d="M431.744684,156.625036 C403.277273,127.938513 365.210476,110.819255 324.872458,108.554334 C301.020986,44.6733227 240.705067,1.74281062 172.561159,0.139719127 C104.417253,-1.46337349 42.1608728,38.5918675 15.3325638,101.281591 C-11.4883973,163.978669 2.52847633,236.691395 50.7238808,284.916521 C80.1100689,314.500188 119.58076,331.884177 161.234467,333.59022 C177.948871,376.439842 211.774593,410.369505 254.560234,427.201973 C297.345877,444.041792 345.210522,442.262214 386.629021,422.289744 L434.772976,470.463396 L440.26359,507.834561 C441.21177,514.268991 445.754206,519.59302 451.957794,521.534379 L486.231879,532.270685 L492.707424,560.707184 C494.030464,566.531261 498.322993,571.230233 504.004714,573.068641 L537.712833,583.966726 L543.012342,610.79278 C544.577939,618.727351 551.5386,624.448477 559.623844,624.448477 L559.82965,624.448477 L617.521543,623.749883 C626.033099,623.654285 633.148114,617.234563 634.140394,608.770531 L634.191844,608.285192 C634.272697,607.608658 634.309448,606.92477 634.309448,606.240881 L633.971339,535.572466 C633.949288,531.10881 632.163185,526.828995 629.009939,523.674287 L459.263915,353.84948 C495.110947,289.328701 483.887157,208.850538 431.744684,156.625036 Z M284.505039,263.465973 C292.318324,268.62087 302.821792,266.466256 307.966948,258.656698 C314.273437,249.096973 319.565597,238.904838 323.762574,228.242071 C324.071282,228.536216 324.387342,228.8083 324.688703,229.117152 C337.184078,241.566852 339.550851,260.943677 330.414524,276.040685 C321.28555,291.130343 303.020247,298.020697 286.202939,292.718727 C269.385631,287.409403 258.375,271.290239 259.543686,253.68564 C260.712372,236.081043 273.759014,221.56497 291.134939,218.535275 C287.996395,226.021273 284.166928,233.205772 279.697993,239.993176 C274.552838,247.810088 276.706454,258.31843 284.512389,263.465973 L284.505039,263.465973 Z M74.6709047,72.9259808 C105.269877,42.32016 148.849344,28.5320971 191.480631,35.9666209 C234.104566,43.4011446 270.451415,71.1316943 288.893121,110.289793 C199.139561,124.702914 137.890163,208.95349 151.840883,298.822242 C122.609051,295.189548 95.4426308,281.85741 74.6782544,260.951032 C22.8738905,208.990258 22.8738905,124.886755 74.6709047,72.9259808 Z M222.189857,366.284473 C186.666235,330.737011 174.538368,278.018814 190.958765,230.506988 C207.386511,182.995164 249.481232,149.036086 299.374537,143.050228 C301.829512,156.602974 302.182322,170.45722 300.40357,184.112916 C265.813425,182.826032 235.199751,206.335597 227.504068,240.096126 C219.801036,273.86401 237.199011,308.330489 268.929919,322.170028 C300.660826,336.01692 337.742697,325.317383 357.235484,296.704396 C376.735624,268.091408 373.119314,229.646613 348.643075,205.159015 C344.063886,200.599763 338.896681,196.665569 333.273762,193.481446 C335.934541,176.921064 336.088896,160.051828 333.736825,143.447325 C378.455575,149.918522 416.706129,178.935958 435.000833,220.263377 C453.295535,261.590796 449.069157,309.426182 423.813794,346.907651 C401.895434,379.418063 366.592317,400.42004 327.57734,404.177747 C288.562362,407.928099 249.914894,394.037086 222.204559,366.299181 L222.189857,366.284473 Z M600.358775,590.077596 L573.508413,590.401156 L569.010079,567.634307 C567.819342,561.604328 563.453309,556.692101 557.609884,554.794863 L523.593057,543.793827 L517.095461,515.254377 C515.75037,509.37147 511.391689,504.650437 505.643814,502.848797 L472.229706,492.377223 L467.474112,459.984469 C466.944896,456.38119 465.269046,453.042639 462.689118,450.468867 L416.213664,403.964492 C421.674879,399.721444 426.871487,395.140132 431.759384,390.249964 C434.427515,387.573242 436.970691,384.786216 439.447717,381.955066 L600.138267,542.720198 L600.358775,590.077596 Z"/>
8
+ </g>
9
+ <path fill="#E48E66" d="M105.588272,885.011198 C91.7515763,885.011198 82,877.015677 82,862.62374 L82,862.357223 C82,847.832027 92.6740227,839.703247 109.409836,839.703247 C115.471627,839.703247 123.246532,841.035834 126.409206,842.368421 L126.409206,841.169093 C126.409206,834.506159 122.324086,830.641657 113.099622,830.641657 C105.72005,830.641657 99.5264817,832.240761 93.2011349,834.772676 L87.9300126,814.650616 C96.2320303,811.452408 105.72005,809.320269 118.238966,809.320269 C132.86633,809.320269 142.354351,812.385218 148.679697,818.781635 C154.082598,824.245241 156.191047,831.307951 156.191047,841.835386 L156.191047,883.278835 L126.277427,883.278835 L126.277427,875.949608 C121.269861,881.413214 114.54918,885.011198 105.588272,885.011198 Z M117.448298,867.554311 C122.71942,867.554311 126.672762,863.290034 126.672762,856.360582 L126.672762,853.295633 C124.959647,852.629339 122.324086,852.096305 119.820303,852.096305 C113.89029,852.096305 110.595839,855.694289 110.595839,860.225084 L110.595839,860.491601 C110.595839,864.755879 113.626734,867.554311 117.448298,867.554311 Z M196.64691,884.87794 C178.988651,884.87794 169.500631,876.615901 169.500631,858.892497 L169.500631,833.839866 L161.066835,833.839866 L161.066835,810.519597 L169.500631,810.519597 L169.500631,792.263158 L199.41425,792.263158 L199.41425,810.519597 L216.018285,810.519597 L216.018285,833.839866 L199.41425,833.839866 L199.41425,852.229563 C199.41425,857.693169 201.918033,859.692049 206.662043,859.692049 C209.429382,859.692049 212.592055,858.892497 215.754729,857.426652 L215.754729,880.74692 C211.010719,883.278835 203.894704,884.87794 196.64691,884.87794 Z M255.419924,884.87794 C237.761665,884.87794 228.273644,876.615901 228.273644,858.892497 L228.273644,833.839866 L219.839849,833.839866 L219.839849,810.519597 L228.273644,810.519597 L228.273644,792.263158 L258.187264,792.263158 L258.187264,810.519597 L274.791299,810.519597 L274.791299,833.839866 L258.187264,833.839866 L258.187264,852.229563 C258.187264,857.693169 260.691047,859.692049 265.435057,859.692049 C268.202396,859.692049 271.365069,858.892497 274.527743,857.426652 L274.527743,880.74692 C269.783733,883.278835 262.667718,884.87794 255.419924,884.87794 Z M281.51198,883.278835 L281.51198,810.519597 L311.425599,810.519597 L311.425599,825.178052 C315.510719,815.316909 322.099622,808.920493 333.959647,809.453527 L333.959647,841.568869 L330.796974,841.568869 C318.14628,841.568869 311.425599,848.631579 311.425599,864.755879 L311.425599,883.278835 L281.51198,883.278835 Z M334.354981,904.600224 L334.354981,889.142217 L413.948928,889.142217 L413.948928,904.600224 L334.354981,904.600224 Z M418.165826,883.278835 L418.165826,786 L448.079445,786 L448.079445,832.907055 L463.497478,810.519597 L496.046658,810.519597 L473.51261,840.103024 L496.441992,883.278835 L464.419924,883.278835 L454.009458,863.290034 L448.079445,871.019037 L448.079445,883.278835 L418.165826,883.278835 Z M531.758512,885.011198 C508.17024,885.011198 492.225095,869.952968 492.225095,847.298992 L492.225095,847.032475 C492.225095,825.31131 507.643127,808.787234 529.254729,808.787234 C554.819672,808.787234 566.679697,826.777156 566.679697,848.898096 C566.679697,850.4972 566.679697,852.362822 566.547919,853.961926 L520.293821,853.961926 C522.40227,860.358343 527.409836,863.68981 533.866961,863.68981 C539.269861,863.68981 543.750315,861.157895 548.494325,856.227324 L564.571248,869.153415 C557.455233,878.481523 547.308323,885.011198 531.758512,885.011198 Z M519.898487,840.636058 L539.401639,840.636058 C538.742749,833.706607 534.657629,829.708847 529.386507,829.708847 C524.378941,829.708847 520.820933,833.973124 519.898487,840.636058 Z M595.143758,905 C584.733291,905 575.377049,901.93505 567.338588,897.404255 L576.035939,876.74916 C581.43884,879.81411 586.446406,881.546473 589.213745,881.546473 C590.92686,881.546473 592.508197,881.279955 594.089533,880.480403 L565.889029,810.519597 L596.856873,810.519597 L609.375788,848.898096 L620.840479,810.519597 L651.281211,810.519597 L626.375158,878.215006 C619.390921,897.270997 611.747793,905 595.143758,905 Z M655.893443,883.278835 L655.893443,810.519597 L685.807062,810.519597 L685.807062,825.178052 C689.892182,815.316909 696.481084,808.920493 708.34111,809.453527 L708.34111,841.568869 L705.178436,841.568869 C692.527743,841.568869 685.807062,848.631579 685.807062,864.755879 L685.807062,883.278835 L655.893443,883.278835 Z M713.216898,805.322508 L713.216898,786 L744.184741,786 L744.184741,805.322508 L713.216898,805.322508 Z M713.74401,883.278835 L713.74401,810.519597 L743.657629,810.519597 L743.657629,883.278835 L713.74401,883.278835 Z M752.882093,883.278835 L752.882093,810.519597 L782.795712,810.519597 L782.795712,820.647256 C787.407945,814.650616 794.655738,808.787234 804.802648,808.787234 C819.957125,808.787234 829.445145,818.914894 829.445145,835.305711 L829.445145,883.278835 L799.531526,883.278835 L799.531526,845.033595 C799.531526,838.770437 795.84174,835.172452 791.361286,835.172452 C786.880832,835.172452 782.795712,838.770437 782.795712,845.033595 L782.795712,883.278835 L752.882093,883.278835 Z M876.226356,904.866741 C860.281211,904.866741 847.894073,901.668533 836.297604,895.805151 L845.522068,877.548712 C853.56053,881.81299 861.598991,884.478163 871.482346,884.478163 C882.68348,884.478163 888.613493,878.614782 888.613493,868.487122 L888.613493,866.354983 C884.528373,871.019037 877.807692,876.349384 867.79256,876.349384 C849.211854,876.349384 835.770492,863.023516 835.770492,842.901456 L835.770492,842.634938 C835.770492,822.246361 849.47541,808.787234 866.079445,808.787234 C876.62169,808.787234 882.815259,812.784994 888.086381,818.2486 L888.086381,810.519597 L918,810.519597 L918,864.889138 C918,878.348264 915.232661,887.543113 908.643758,894.206047 C902.186633,900.735722 892.303279,904.866741 876.226356,904.866741 Z M876.753468,854.228443 C884.133039,854.228443 888.745271,849.164614 888.745271,842.768197 L888.745271,842.50168 C888.745271,836.238522 884.001261,831.174692 876.753468,831.174692 C869.373897,831.174692 864.761665,836.371781 864.761665,842.768197 L864.761665,843.034714 C864.761665,849.297872 869.505675,854.228443 876.753468,854.228443 Z"/>
10
+ <path fill="#63316D" d="M44.3623047,947.111328 L47.5996094,947.111328 C47.8339844,949.206055 49.8701172,950.583008 52.6533203,950.583008 C55.3193359,950.583008 57.2382812,949.206055 57.2382812,947.316406 C57.2382812,945.675781 56.0810547,944.694336 53.3417969,944.020508 L50.6025391,943.361328 C46.7207031,942.423828 44.9189453,940.607422 44.9189453,937.663086 C44.9189453,934.015625 48.0976562,931.510742 52.609375,931.510742 C57.0771484,931.510742 60.1386719,934.015625 60.2412109,937.663086 L57.0478516,937.663086 C56.8574219,935.553711 55.1142578,934.279297 52.5654297,934.279297 C50.0166016,934.279297 48.2734375,935.568359 48.2734375,937.443359 C48.2734375,938.9375 49.3867188,939.816406 52.1113281,940.490234 L54.4404297,941.061523 C58.7763672,942.086914 60.578125,943.830078 60.578125,946.920898 C60.578125,950.875977 57.4287109,953.351562 52.4189453,953.351562 C47.7314453,953.351562 44.5673828,950.93457 44.3623047,947.111328 Z M63.3173828,953 L63.3173828,937.091797 L66.4960938,937.091797 L66.4960938,953 L63.3173828,953 Z M64.9140625,934.821289 C63.8886719,934.821289 63.0537109,934.000977 63.0537109,932.990234 C63.0537109,931.950195 63.8886719,931.15918 64.9140625,931.15918 C65.9394531,931.15918 66.7744141,931.950195 66.7744141,932.990234 C66.7744141,934.000977 65.9394531,934.821289 64.9140625,934.821289 Z M69.8652344,953 L69.8652344,937.091797 L72.8974609,937.091797 L72.8974609,939.787109 L72.9560547,939.787109 C73.6884766,938 75.4023438,936.916016 77.4824219,936.916016 C79.6943359,936.916016 81.2910156,938.029297 81.9355469,940.006836 L82.0087891,940.006836 C82.84375,938.087891 84.71875,936.916016 86.9892578,936.916016 C90.1240234,936.916016 92.1748047,938.981445 92.1748047,942.160156 L92.1748047,953 L89.0107422,953 L89.0107422,942.921875 C89.0107422,940.841797 87.8828125,939.640625 85.9052734,939.640625 C83.9570312,939.640625 82.5800781,941.09082 82.5800781,943.126953 L82.5800781,953 L79.4599609,953 L79.4599609,942.658203 C79.4599609,940.8125 78.2734375,939.640625 76.4130859,939.640625 C74.4501953,939.640625 73.0439453,941.164062 73.0439453,943.244141 L73.0439453,953 L69.8652344,953 Z M103.556641,936.930664 C107.614258,936.930664 110.280273,940.109375 110.280273,945.045898 C110.280273,949.967773 107.628906,953.161133 103.629883,953.161133 C101.344727,953.161133 99.5429688,952.150391 98.5908203,950.392578 L98.5322266,950.392578 L98.5322266,958.273438 L95.3535156,958.273438 L95.3535156,937.091797 L98.4150391,937.091797 L98.4150391,939.728516 L98.4882812,939.728516 C99.3818359,938.014648 101.344727,936.930664 103.556641,936.930664 Z M102.750977,950.46582 C105.329102,950.46582 107.02832,948.341797 107.02832,945.045898 C107.02832,941.764648 105.329102,939.625977 102.750977,939.625977 C100.231445,939.625977 98.5175781,941.808594 98.5029297,945.045898 C98.5175781,948.297852 100.216797,950.46582 102.750977,950.46582 Z M112.946289,953 L112.946289,930.910156 L116.125,930.910156 L116.125,953 L112.946289,953 Z M126.129883,939.479492 C123.844727,939.479492 122.189453,941.149414 122.013672,943.595703 L130.084961,943.595703 C130.011719,941.120117 128.444336,939.479492 126.129883,939.479492 Z M130.070312,948.341797 L133.102539,948.341797 C132.648438,951.198242 129.850586,953.19043 126.276367,953.19043 C121.662109,953.19043 118.791016,950.084961 118.791016,945.104492 C118.791016,940.124023 121.691406,936.886719 126.144531,936.886719 C130.509766,936.886719 133.263672,939.918945 133.263672,944.738281 L133.263672,945.851562 L121.999023,945.851562 L121.999023,946.041992 C121.999023,948.795898 123.727539,950.612305 126.334961,950.612305 C128.180664,950.612305 129.630859,949.733398 130.070312,948.341797 Z M149.347656,939.479492 C147.0625,939.479492 145.407227,941.149414 145.231445,943.595703 L153.302734,943.595703 C153.229492,941.120117 151.662109,939.479492 149.347656,939.479492 Z M153.288086,948.341797 L156.320312,948.341797 C155.866211,951.198242 153.068359,953.19043 149.494141,953.19043 C144.879883,953.19043 142.008789,950.084961 142.008789,945.104492 C142.008789,940.124023 144.90918,936.886719 149.362305,936.886719 C153.727539,936.886719 156.481445,939.918945 156.481445,944.738281 L156.481445,945.851562 L145.216797,945.851562 L145.216797,946.041992 C145.216797,948.795898 146.945312,950.612305 149.552734,950.612305 C151.398438,950.612305 152.848633,949.733398 153.288086,948.341797 Z M159.030273,953 L159.030273,937.091797 L162.0625,937.091797 L162.0625,939.772461 L162.121094,939.772461 C163.087891,937.897461 164.68457,936.916016 167.145508,936.916016 C170.661133,936.916016 172.667969,939.142578 172.667969,942.804688 L172.667969,953 L169.489258,953 L169.489258,943.405273 C169.489258,940.988281 168.375977,939.640625 166.046875,939.640625 C163.644531,939.640625 162.208984,941.310547 162.208984,943.81543 L162.208984,953 L159.030273,953 Z M189.44043,942.526367 L186.408203,942.526367 C186.115234,940.841797 184.796875,939.567383 182.614258,939.567383 C180.050781,939.567383 178.351562,941.706055 178.351562,945.045898 C178.351562,948.473633 180.080078,950.524414 182.628906,950.524414 C184.694336,950.524414 186.056641,949.513672 186.4375,947.65332 L189.469727,947.65332 C189.103516,950.978516 186.4375,953.19043 182.614258,953.19043 C178.102539,953.19043 175.128906,950.084961 175.128906,945.045898 C175.128906,940.094727 178.087891,936.886719 182.584961,936.886719 C186.642578,936.886719 189.162109,939.464844 189.44043,942.526367 Z M191.798828,953 L191.798828,937.091797 L194.831055,937.091797 L194.831055,939.772461 L194.889648,939.772461 C195.387695,938 196.852539,936.930664 198.727539,936.930664 C199.196289,936.930664 199.591797,936.974609 199.84082,937.033203 L199.84082,940.006836 C199.577148,939.904297 199.020508,939.816406 198.390625,939.816406 C196.295898,939.816406 194.977539,941.266602 194.977539,943.507812 L194.977539,953 L191.798828,953 Z M203.473633,958.786133 C203.209961,958.786133 202.433594,958.742188 202.18457,958.698242 L202.18457,956.120117 C202.418945,956.178711 202.916992,956.193359 203.195312,956.193359 C204.704102,956.193359 205.539062,955.548828 206.081055,953.864258 L206.330078,953.043945 L200.558594,937.091797 L203.97168,937.091797 L208.058594,950.099609 L208.131836,950.099609 L212.21875,937.091797 L215.558594,937.091797 L209.59668,953.732422 C208.234375,957.555664 206.725586,958.786133 203.473633,958.786133 Z M225.695312,936.930664 C229.75293,936.930664 232.418945,940.109375 232.418945,945.045898 C232.418945,949.967773 229.767578,953.161133 225.768555,953.161133 C223.483398,953.161133 221.681641,952.150391 220.729492,950.392578 L220.670898,950.392578 L220.670898,958.273438 L217.492188,958.273438 L217.492188,937.091797 L220.553711,937.091797 L220.553711,939.728516 L220.626953,939.728516 C221.520508,938.014648 223.483398,936.930664 225.695312,936.930664 Z M224.889648,950.46582 C227.467773,950.46582 229.166992,948.341797 229.166992,945.045898 C229.166992,941.764648 227.467773,939.625977 224.889648,939.625977 C222.370117,939.625977 220.65625,941.808594 220.641602,945.045898 C220.65625,948.297852 222.355469,950.46582 224.889648,950.46582 Z M235.905273,933.517578 L239.069336,933.517578 L239.069336,937.091797 L242.116211,937.091797 L242.116211,939.59668 L239.069336,939.59668 L239.069336,948.488281 C239.069336,949.865234 239.68457,950.509766 241.017578,950.509766 C241.354492,950.509766 241.896484,950.46582 242.101562,950.436523 L242.101562,952.941406 C241.75,953.029297 241.00293,953.102539 240.314453,953.102539 C237.135742,953.102539 235.905273,951.886719 235.905273,948.810547 L235.905273,939.59668 L233.708008,939.59668 L233.708008,937.091797 L235.905273,937.091797 L235.905273,933.517578 Z M244.914062,953 L244.914062,937.091797 L248.092773,937.091797 L248.092773,953 L244.914062,953 Z M246.510742,934.821289 C245.485352,934.821289 244.650391,934.000977 244.650391,932.990234 C244.650391,931.950195 245.485352,931.15918 246.510742,931.15918 C247.536133,931.15918 248.371094,931.950195 248.371094,932.990234 C248.371094,934.000977 247.536133,934.821289 246.510742,934.821289 Z M258.273438,953.19043 C253.673828,953.19043 250.744141,950.055664 250.744141,945.045898 C250.744141,940.050781 253.688477,936.886719 258.273438,936.886719 C262.858398,936.886719 265.788086,940.036133 265.788086,945.045898 C265.788086,950.055664 262.873047,953.19043 258.273438,953.19043 Z M258.273438,950.553711 C260.96875,950.553711 262.56543,948.517578 262.56543,945.045898 C262.56543,941.574219 260.96875,939.523438 258.273438,939.523438 C255.578125,939.523438 253.966797,941.588867 253.966797,945.045898 C253.966797,948.517578 255.578125,950.553711 258.273438,950.553711 Z M268.336914,953 L268.336914,937.091797 L271.369141,937.091797 L271.369141,939.772461 L271.427734,939.772461 C272.394531,937.897461 273.991211,936.916016 276.452148,936.916016 C279.967773,936.916016 281.974609,939.142578 281.974609,942.804688 L281.974609,953 L278.795898,953 L278.795898,943.405273 C278.795898,940.988281 277.682617,939.640625 275.353516,939.640625 C272.951172,939.640625 271.515625,941.310547 271.515625,943.81543 L271.515625,953 L268.336914,953 Z M294.835938,946.041992 L285.226562,946.041992 L285.226562,943.185547 L294.835938,943.185547 L294.835938,946.041992 Z M303.683594,950.626953 C306.041992,950.626953 307.829102,949.118164 307.829102,947.023438 L307.829102,945.77832 L303.961914,946.041992 C301.793945,946.173828 300.666016,946.979492 300.666016,948.385742 C300.666016,949.748047 301.852539,950.626953 303.683594,950.626953 Z M302.833984,953.161133 C299.655273,953.161133 297.458008,951.286133 297.458008,948.444336 C297.458008,945.661133 299.611328,944.049805 303.537109,943.800781 L307.829102,943.551758 L307.829102,942.321289 C307.829102,940.504883 306.613281,939.508789 304.489258,939.508789 C302.760742,939.508789 301.500977,940.402344 301.222656,941.779297 L298.249023,941.779297 C298.336914,938.966797 301.00293,936.886719 304.577148,936.886719 C308.458984,936.886719 310.963867,938.9375 310.963867,942.086914 L310.963867,953 L307.931641,953 L307.931641,950.348633 L307.858398,950.348633 C306.979492,952.077148 305.001953,953.161133 302.833984,953.161133 Z M315.109375,933.517578 L318.273438,933.517578 L318.273438,937.091797 L321.320312,937.091797 L321.320312,939.59668 L318.273438,939.59668 L318.273438,948.488281 C318.273438,949.865234 318.888672,950.509766 320.22168,950.509766 C320.558594,950.509766 321.100586,950.46582 321.305664,950.436523 L321.305664,952.941406 C320.954102,953.029297 320.207031,953.102539 319.518555,953.102539 C316.339844,953.102539 315.109375,951.886719 315.109375,948.810547 L315.109375,939.59668 L312.912109,939.59668 L312.912109,937.091797 L315.109375,937.091797 L315.109375,933.517578 Z M333.610352,946.041992 L324.000977,946.041992 L324.000977,943.185547 L333.610352,943.185547 L333.610352,946.041992 Z M336.935547,953 L336.935547,937.091797 L339.967773,937.091797 L339.967773,939.772461 L340.026367,939.772461 C340.524414,938 341.989258,936.930664 343.864258,936.930664 C344.333008,936.930664 344.728516,936.974609 344.977539,937.033203 L344.977539,940.006836 C344.713867,939.904297 344.157227,939.816406 343.527344,939.816406 C341.432617,939.816406 340.114258,941.266602 340.114258,943.507812 L340.114258,953 L336.935547,953 Z M352.975586,939.479492 C350.69043,939.479492 349.035156,941.149414 348.859375,943.595703 L356.930664,943.595703 C356.857422,941.120117 355.290039,939.479492 352.975586,939.479492 Z M356.916016,948.341797 L359.948242,948.341797 C359.494141,951.198242 356.696289,953.19043 353.12207,953.19043 C348.507812,953.19043 345.636719,950.084961 345.636719,945.104492 C345.636719,940.124023 348.537109,936.886719 352.990234,936.886719 C357.355469,936.886719 360.109375,939.918945 360.109375,944.738281 L360.109375,945.851562 L348.844727,945.851562 L348.844727,946.041992 C348.844727,948.795898 350.573242,950.612305 353.180664,950.612305 C355.026367,950.612305 356.476562,949.733398 356.916016,948.341797 Z M362.394531,941.618164 C362.394531,938.820312 364.899414,936.901367 368.561523,936.901367 C372.047852,936.901367 374.567383,938.864258 374.640625,941.632812 L371.652344,941.632812 C371.520508,940.226562 370.304688,939.347656 368.488281,939.347656 C366.686523,939.347656 365.485352,940.182617 365.485352,941.442383 C365.485352,942.40918 366.276367,943.068359 367.960938,943.478516 L370.597656,944.108398 C373.805664,944.884766 374.992188,946.041992 374.992188,948.385742 C374.992188,951.227539 372.296875,953.19043 368.444336,953.19043 C364.738281,953.19043 362.204102,951.271484 361.969727,948.400391 L365.104492,948.400391 C365.353516,949.923828 366.583984,950.758789 368.605469,950.758789 C370.583008,950.758789 371.828125,949.938477 371.828125,948.649414 C371.828125,947.638672 371.198242,947.111328 369.52832,946.686523 L366.686523,945.983398 C363.81543,945.280273 362.394531,943.81543 362.394531,941.618164 Z M378.522461,933.517578 L381.686523,933.517578 L381.686523,937.091797 L384.733398,937.091797 L384.733398,939.59668 L381.686523,939.59668 L381.686523,948.488281 C381.686523,949.865234 382.301758,950.509766 383.634766,950.509766 C383.97168,950.509766 384.513672,950.46582 384.71875,950.436523 L384.71875,952.941406 C384.367188,953.029297 383.620117,953.102539 382.931641,953.102539 C379.75293,953.102539 378.522461,951.886719 378.522461,948.810547 L378.522461,939.59668 L376.325195,939.59668 L376.325195,937.091797 L378.522461,937.091797 L378.522461,933.517578 Z M415.216797,937.091797 L410.836914,953 L407.555664,953 L404.171875,941.017578 L404.098633,941.017578 L400.744141,953 L397.477539,953 L393.083008,937.091797 L396.24707,937.091797 L399.206055,949.689453 L399.264648,949.689453 L402.633789,937.091797 L405.680664,937.091797 L409.064453,949.689453 L409.123047,949.689453 L412.082031,937.091797 L415.216797,937.091797 Z M417.34082,953 L417.34082,937.091797 L420.519531,937.091797 L420.519531,953 L417.34082,953 Z M418.9375,934.821289 C417.912109,934.821289 417.077148,934.000977 417.077148,932.990234 C417.077148,931.950195 417.912109,931.15918 418.9375,931.15918 C419.962891,931.15918 420.797852,931.950195 420.797852,932.990234 C420.797852,934.000977 419.962891,934.821289 418.9375,934.821289 Z M424.84082,933.517578 L428.004883,933.517578 L428.004883,937.091797 L431.051758,937.091797 L431.051758,939.59668 L428.004883,939.59668 L428.004883,948.488281 C428.004883,949.865234 428.620117,950.509766 429.953125,950.509766 C430.290039,950.509766 430.832031,950.46582 431.037109,950.436523 L431.037109,952.941406 C430.685547,953.029297 429.938477,953.102539 429.25,953.102539 C426.071289,953.102539 424.84082,951.886719 424.84082,948.810547 L424.84082,939.59668 L422.643555,939.59668 L422.643555,937.091797 L424.84082,937.091797 L424.84082,933.517578 Z M433.864258,953 L433.864258,930.910156 L437.013672,930.910156 L437.013672,939.772461 L437.086914,939.772461 C438.039062,937.897461 439.679688,936.916016 442.111328,936.916016 C445.612305,936.916016 447.707031,939.245117 447.707031,942.833984 L447.707031,953 L444.52832,953 L444.52832,943.449219 C444.52832,941.076172 443.341797,939.640625 441.012695,939.640625 C438.537109,939.640625 437.042969,941.339844 437.042969,943.888672 L437.042969,953 L433.864258,953 Z M461.125,943.961914 L467.672852,937.091797 L471.408203,937.091797 L464.757812,943.947266 L471.642578,953 L467.980469,953 L462.487305,945.880859 L461.110352,947.228516 L461.110352,953 L457.931641,953 L457.931641,930.910156 L461.110352,930.910156 L461.110352,943.961914 L461.125,943.961914 Z M479.245117,939.479492 C476.959961,939.479492 475.304688,941.149414 475.128906,943.595703 L483.200195,943.595703 C483.126953,941.120117 481.55957,939.479492 479.245117,939.479492 Z M483.185547,948.341797 L486.217773,948.341797 C485.763672,951.198242 482.96582,953.19043 479.391602,953.19043 C474.777344,953.19043 471.90625,950.084961 471.90625,945.104492 C471.90625,940.124023 474.806641,936.886719 479.259766,936.886719 C483.625,936.886719 486.378906,939.918945 486.378906,944.738281 L486.378906,945.851562 L475.114258,945.851562 L475.114258,946.041992 C475.114258,948.795898 476.842773,950.612305 479.450195,950.612305 C481.295898,950.612305 482.746094,949.733398 483.185547,948.341797 Z M490.451172,958.786133 C490.1875,958.786133 489.411133,958.742188 489.162109,958.698242 L489.162109,956.120117 C489.396484,956.178711 489.894531,956.193359 490.172852,956.193359 C491.681641,956.193359 492.516602,955.548828 493.058594,953.864258 L493.307617,953.043945 L487.536133,937.091797 L490.949219,937.091797 L495.036133,950.099609 L495.109375,950.099609 L499.196289,937.091797 L502.536133,937.091797 L496.574219,953.732422 C495.211914,957.555664 493.703125,958.786133 490.451172,958.786133 Z M511.383789,953 L511.383789,937.091797 L514.416016,937.091797 L514.416016,939.772461 L514.474609,939.772461 C514.972656,938 516.4375,936.930664 518.3125,936.930664 C518.78125,936.930664 519.176758,936.974609 519.425781,937.033203 L519.425781,940.006836 C519.162109,939.904297 518.605469,939.816406 517.975586,939.816406 C515.880859,939.816406 514.5625,941.266602 514.5625,943.507812 L514.5625,953 L511.383789,953 Z M527.614258,953.19043 C523.014648,953.19043 520.084961,950.055664 520.084961,945.045898 C520.084961,940.050781 523.029297,936.886719 527.614258,936.886719 C532.199219,936.886719 535.128906,940.036133 535.128906,945.045898 C535.128906,950.055664 532.213867,953.19043 527.614258,953.19043 Z M527.614258,950.553711 C530.30957,950.553711 531.90625,948.517578 531.90625,945.045898 C531.90625,941.574219 530.30957,939.523438 527.614258,939.523438 C524.918945,939.523438 523.307617,941.588867 523.307617,945.045898 C523.307617,948.517578 524.918945,950.553711 527.614258,950.553711 Z M538.629883,933.517578 L541.793945,933.517578 L541.793945,937.091797 L544.84082,937.091797 L544.84082,939.59668 L541.793945,939.59668 L541.793945,948.488281 C541.793945,949.865234 542.40918,950.509766 543.742188,950.509766 C544.079102,950.509766 544.621094,950.46582 544.826172,950.436523 L544.826172,952.941406 C544.474609,953.029297 543.727539,953.102539 543.039062,953.102539 C539.860352,953.102539 538.629883,951.886719 538.629883,948.810547 L538.629883,939.59668 L536.432617,939.59668 L536.432617,937.091797 L538.629883,937.091797 L538.629883,933.517578 Z M552.926758,950.626953 C555.285156,950.626953 557.072266,949.118164 557.072266,947.023438 L557.072266,945.77832 L553.205078,946.041992 C551.037109,946.173828 549.90918,946.979492 549.90918,948.385742 C549.90918,949.748047 551.095703,950.626953 552.926758,950.626953 Z M552.077148,953.161133 C548.898438,953.161133 546.701172,951.286133 546.701172,948.444336 C546.701172,945.661133 548.854492,944.049805 552.780273,943.800781 L557.072266,943.551758 L557.072266,942.321289 C557.072266,940.504883 555.856445,939.508789 553.732422,939.508789 C552.003906,939.508789 550.744141,940.402344 550.46582,941.779297 L547.492188,941.779297 C547.580078,938.966797 550.246094,936.886719 553.820312,936.886719 C557.702148,936.886719 560.207031,938.9375 560.207031,942.086914 L560.207031,953 L557.174805,953 L557.174805,950.348633 L557.101562,950.348633 C556.222656,952.077148 554.245117,953.161133 552.077148,953.161133 Z M564.352539,933.517578 L567.516602,933.517578 L567.516602,937.091797 L570.563477,937.091797 L570.563477,939.59668 L567.516602,939.59668 L567.516602,948.488281 C567.516602,949.865234 568.131836,950.509766 569.464844,950.509766 C569.801758,950.509766 570.34375,950.46582 570.548828,950.436523 L570.548828,952.941406 C570.197266,953.029297 569.450195,953.102539 568.761719,953.102539 C565.583008,953.102539 564.352539,951.886719 564.352539,948.810547 L564.352539,939.59668 L562.155273,939.59668 L562.155273,937.091797 L564.352539,937.091797 L564.352539,933.517578 Z M573.361328,953 L573.361328,937.091797 L576.540039,937.091797 L576.540039,953 L573.361328,953 Z M574.958008,934.821289 C573.932617,934.821289 573.097656,934.000977 573.097656,932.990234 C573.097656,931.950195 573.932617,931.15918 574.958008,931.15918 C575.983398,931.15918 576.818359,931.950195 576.818359,932.990234 C576.818359,934.000977 575.983398,934.821289 574.958008,934.821289 Z M586.720703,953.19043 C582.121094,953.19043 579.191406,950.055664 579.191406,945.045898 C579.191406,940.050781 582.135742,936.886719 586.720703,936.886719 C591.305664,936.886719 594.235352,940.036133 594.235352,945.045898 C594.235352,950.055664 591.320312,953.19043 586.720703,953.19043 Z M586.720703,950.553711 C589.416016,950.553711 591.012695,948.517578 591.012695,945.045898 C591.012695,941.574219 589.416016,939.523438 586.720703,939.523438 C584.025391,939.523438 582.414062,941.588867 582.414062,945.045898 C582.414062,948.517578 584.025391,950.553711 586.720703,950.553711 Z M596.78418,953 L596.78418,937.091797 L599.816406,937.091797 L599.816406,939.772461 L599.875,939.772461 C600.841797,937.897461 602.438477,936.916016 604.899414,936.916016 C608.415039,936.916016 610.421875,939.142578 610.421875,942.804688 L610.421875,953 L607.243164,953 L607.243164,943.405273 C607.243164,940.988281 606.129883,939.640625 603.800781,939.640625 C601.398438,939.640625 599.962891,941.310547 599.962891,943.81543 L599.962891,953 L596.78418,953 Z M620.250977,941.618164 C620.250977,938.820312 622.755859,936.901367 626.417969,936.901367 C629.904297,936.901367 632.423828,938.864258 632.49707,941.632812 L629.508789,941.632812 C629.376953,940.226562 628.161133,939.347656 626.344727,939.347656 C624.542969,939.347656 623.341797,940.182617 623.341797,941.442383 C623.341797,942.40918 624.132812,943.068359 625.817383,943.478516 L628.454102,944.108398 C631.662109,944.884766 632.848633,946.041992 632.848633,948.385742 C632.848633,951.227539 630.15332,953.19043 626.300781,953.19043 C622.594727,953.19043 620.060547,951.271484 619.826172,948.400391 L622.960938,948.400391 C623.209961,949.923828 624.44043,950.758789 626.461914,950.758789 C628.439453,950.758789 629.68457,949.938477 629.68457,948.649414 C629.68457,947.638672 629.054688,947.111328 627.384766,946.686523 L624.542969,945.983398 C621.671875,945.280273 620.250977,943.81543 620.250977,941.618164 Z M648.991211,937.091797 L648.991211,953 L645.958984,953 L645.958984,950.275391 L645.900391,950.275391 C644.977539,952.165039 643.366211,953.175781 640.93457,953.175781 C637.462891,953.175781 635.353516,950.93457 635.353516,947.287109 L635.353516,937.091797 L638.532227,937.091797 L638.532227,946.686523 C638.532227,949.132812 639.689453,950.436523 641.989258,950.436523 C644.362305,950.436523 645.8125,948.78125 645.8125,946.261719 L645.8125,937.091797 L648.991211,937.091797 Z M660.446289,936.930664 C664.503906,936.930664 667.169922,940.109375 667.169922,945.045898 C667.169922,949.967773 664.518555,953.161133 660.519531,953.161133 C658.234375,953.161133 656.432617,952.150391 655.480469,950.392578 L655.421875,950.392578 L655.421875,958.273438 L652.243164,958.273438 L652.243164,937.091797 L655.304688,937.091797 L655.304688,939.728516 L655.37793,939.728516 C656.271484,938.014648 658.234375,936.930664 660.446289,936.930664 Z M659.640625,950.46582 C662.21875,950.46582 663.917969,948.341797 663.917969,945.045898 C663.917969,941.764648 662.21875,939.625977 659.640625,939.625977 C657.121094,939.625977 655.407227,941.808594 655.392578,945.045898 C655.407227,948.297852 657.106445,950.46582 659.640625,950.46582 Z M677.907227,936.930664 C681.964844,936.930664 684.630859,940.109375 684.630859,945.045898 C684.630859,949.967773 681.979492,953.161133 677.980469,953.161133 C675.695312,953.161133 673.893555,952.150391 672.941406,950.392578 L672.882812,950.392578 L672.882812,958.273438 L669.704102,958.273438 L669.704102,937.091797 L672.765625,937.091797 L672.765625,939.728516 L672.838867,939.728516 C673.732422,938.014648 675.695312,936.930664 677.907227,936.930664 Z M677.101562,950.46582 C679.679688,950.46582 681.378906,948.341797 681.378906,945.045898 C681.378906,941.764648 679.679688,939.625977 677.101562,939.625977 C674.582031,939.625977 672.868164,941.808594 672.853516,945.045898 C672.868164,948.297852 674.567383,950.46582 677.101562,950.46582 Z M693.976562,953.19043 C689.376953,953.19043 686.447266,950.055664 686.447266,945.045898 C686.447266,940.050781 689.391602,936.886719 693.976562,936.886719 C698.561523,936.886719 701.491211,940.036133 701.491211,945.045898 C701.491211,950.055664 698.576172,953.19043 693.976562,953.19043 Z M693.976562,950.553711 C696.671875,950.553711 698.268555,948.517578 698.268555,945.045898 C698.268555,941.574219 696.671875,939.523438 693.976562,939.523438 C691.28125,939.523438 689.669922,941.588867 689.669922,945.045898 C689.669922,948.517578 691.28125,950.553711 693.976562,950.553711 Z M704.040039,953 L704.040039,937.091797 L707.072266,937.091797 L707.072266,939.772461 L707.130859,939.772461 C707.628906,938 709.09375,936.930664 710.96875,936.930664 C711.4375,936.930664 711.833008,936.974609 712.082031,937.033203 L712.082031,940.006836 C711.818359,939.904297 711.261719,939.816406 710.631836,939.816406 C708.537109,939.816406 707.21875,941.266602 707.21875,943.507812 L707.21875,953 L704.040039,953 Z M715.070312,933.517578 L718.234375,933.517578 L718.234375,937.091797 L721.28125,937.091797 L721.28125,939.59668 L718.234375,939.59668 L718.234375,948.488281 C718.234375,949.865234 718.849609,950.509766 720.182617,950.509766 C720.519531,950.509766 721.061523,950.46582 721.266602,950.436523 L721.266602,952.941406 C720.915039,953.029297 720.167969,953.102539 719.479492,953.102539 C716.300781,953.102539 715.070312,951.886719 715.070312,948.810547 L715.070312,939.59668 L712.873047,939.59668 L712.873047,937.091797 L715.070312,937.091797 L715.070312,933.517578 Z M731.828125,953 L731.828125,939.59668 L729.630859,939.59668 L729.630859,937.091797 L731.828125,937.091797 L731.828125,935.626953 C731.828125,932.65332 733.175781,931.349609 736.398438,931.349609 C736.969727,931.349609 737.49707,931.408203 738.009766,931.496094 L738.009766,933.913086 C737.6875,933.839844 737.248047,933.795898 736.823242,933.795898 C735.519531,933.795898 734.977539,934.367188 734.962891,935.729492 L734.962891,937.091797 L738.024414,937.091797 L738.024414,939.59668 L734.992188,939.59668 L734.992188,953 L731.828125,953 Z M746.828125,953.19043 C742.228516,953.19043 739.298828,950.055664 739.298828,945.045898 C739.298828,940.050781 742.243164,936.886719 746.828125,936.886719 C751.413086,936.886719 754.342773,940.036133 754.342773,945.045898 C754.342773,950.055664 751.427734,953.19043 746.828125,953.19043 Z M746.828125,950.553711 C749.523438,950.553711 751.120117,948.517578 751.120117,945.045898 C751.120117,941.574219 749.523438,939.523438 746.828125,939.523438 C744.132812,939.523438 742.521484,941.588867 742.521484,945.045898 C742.521484,948.517578 744.132812,950.553711 746.828125,950.553711 Z M756.891602,953 L756.891602,937.091797 L759.923828,937.091797 L759.923828,939.772461 L759.982422,939.772461 C760.480469,938 761.945312,936.930664 763.820312,936.930664 C764.289062,936.930664 764.68457,936.974609 764.933594,937.033203 L764.933594,940.006836 C764.669922,939.904297 764.113281,939.816406 763.483398,939.816406 C761.388672,939.816406 760.070312,941.266602 760.070312,943.507812 L760.070312,953 L756.891602,953 Z M787.975586,953 L786.041992,947.287109 L777.985352,947.287109 L776.051758,953 L772.638672,953 L780.270508,931.862305 L783.81543,931.862305 L791.447266,953 L787.975586,953 Z M781.969727,935.37793 L778.820312,944.650391 L785.207031,944.650391 L782.057617,935.37793 L781.969727,935.37793 Z M806.652344,942.526367 L803.620117,942.526367 C803.327148,940.841797 802.008789,939.567383 799.826172,939.567383 C797.262695,939.567383 795.563477,941.706055 795.563477,945.045898 C795.563477,948.473633 797.291992,950.524414 799.84082,950.524414 C801.90625,950.524414 803.268555,949.513672 803.649414,947.65332 L806.681641,947.65332 C806.31543,950.978516 803.649414,953.19043 799.826172,953.19043 C795.314453,953.19043 792.34082,950.084961 792.34082,945.045898 C792.34082,940.094727 795.299805,936.886719 799.796875,936.886719 C803.854492,936.886719 806.374023,939.464844 806.652344,942.526367 Z M809.962891,933.517578 L813.126953,933.517578 L813.126953,937.091797 L816.173828,937.091797 L816.173828,939.59668 L813.126953,939.59668 L813.126953,948.488281 C813.126953,949.865234 813.742188,950.509766 815.075195,950.509766 C815.412109,950.509766 815.954102,950.46582 816.15918,950.436523 L816.15918,952.941406 C815.807617,953.029297 815.060547,953.102539 814.37207,953.102539 C811.193359,953.102539 809.962891,951.886719 809.962891,948.810547 L809.962891,939.59668 L807.765625,939.59668 L807.765625,937.091797 L809.962891,937.091797 L809.962891,933.517578 Z M818.97168,953 L818.97168,937.091797 L822.150391,937.091797 L822.150391,953 L818.97168,953 Z M820.568359,934.821289 C819.542969,934.821289 818.708008,934.000977 818.708008,932.990234 C818.708008,931.950195 819.542969,931.15918 820.568359,931.15918 C821.59375,931.15918 822.428711,931.950195 822.428711,932.990234 C822.428711,934.000977 821.59375,934.821289 820.568359,934.821289 Z M839.025391,937.091797 L833.297852,953 L829.914062,953 L824.171875,937.091797 L827.526367,937.091797 L831.583984,949.865234 L831.657227,949.865234 L835.729492,937.091797 L839.025391,937.091797 Z M847.111328,939.479492 C844.826172,939.479492 843.170898,941.149414 842.995117,943.595703 L851.066406,943.595703 C850.993164,941.120117 849.425781,939.479492 847.111328,939.479492 Z M851.051758,948.341797 L854.083984,948.341797 C853.629883,951.198242 850.832031,953.19043 847.257812,953.19043 C842.643555,953.19043 839.772461,950.084961 839.772461,945.104492 C839.772461,940.124023 842.672852,936.886719 847.125977,936.886719 C851.491211,936.886719 854.245117,939.918945 854.245117,944.738281 L854.245117,945.851562 L842.980469,945.851562 L842.980469,946.041992 C842.980469,948.795898 844.708984,950.612305 847.316406,950.612305 C849.162109,950.612305 850.612305,949.733398 851.051758,948.341797 Z M860.397461,934.616211 L860.397461,942.21875 L865.114258,942.21875 C867.648438,942.21875 869.113281,940.827148 869.113281,938.410156 C869.113281,936.051758 867.560547,934.616211 865.026367,934.616211 L860.397461,934.616211 Z M860.397461,944.870117 L860.397461,953 L857.116211,953 L857.116211,931.862305 L865.421875,931.862305 C869.772461,931.862305 872.482422,934.381836 872.482422,938.322266 C872.482422,941.178711 870.958984,943.493164 868.380859,944.357422 L873.126953,953 L869.333008,953 L865.026367,944.870117 L860.397461,944.870117 Z M881.886719,939.479492 C879.601562,939.479492 877.946289,941.149414 877.770508,943.595703 L885.841797,943.595703 C885.768555,941.120117 884.201172,939.479492 881.886719,939.479492 Z M885.827148,948.341797 L888.859375,948.341797 C888.405273,951.198242 885.607422,953.19043 882.033203,953.19043 C877.418945,953.19043 874.547852,950.084961 874.547852,945.104492 C874.547852,940.124023 877.448242,936.886719 881.901367,936.886719 C886.266602,936.886719 889.020508,939.918945 889.020508,944.738281 L889.020508,945.851562 L877.755859,945.851562 L877.755859,946.041992 C877.755859,948.795898 879.484375,950.612305 882.091797,950.612305 C883.9375,950.612305 885.387695,949.733398 885.827148,948.341797 Z M905.163086,942.526367 L902.130859,942.526367 C901.837891,940.841797 900.519531,939.567383 898.336914,939.567383 C895.773438,939.567383 894.074219,941.706055 894.074219,945.045898 C894.074219,948.473633 895.802734,950.524414 898.351562,950.524414 C900.416992,950.524414 901.779297,949.513672 902.160156,947.65332 L905.192383,947.65332 C904.826172,950.978516 902.160156,953.19043 898.336914,953.19043 C893.825195,953.19043 890.851562,950.084961 890.851562,945.045898 C890.851562,940.094727 893.810547,936.886719 898.307617,936.886719 C902.365234,936.886719 904.884766,939.464844 905.163086,942.526367 Z M914.333008,953.19043 C909.733398,953.19043 906.803711,950.055664 906.803711,945.045898 C906.803711,940.050781 909.748047,936.886719 914.333008,936.886719 C918.917969,936.886719 921.847656,940.036133 921.847656,945.045898 C921.847656,950.055664 918.932617,953.19043 914.333008,953.19043 Z M914.333008,950.553711 C917.02832,950.553711 918.625,948.517578 918.625,945.045898 C918.625,941.574219 917.02832,939.523438 914.333008,939.523438 C911.637695,939.523438 910.026367,941.588867 910.026367,945.045898 C910.026367,948.517578 911.637695,950.553711 914.333008,950.553711 Z M924.396484,953 L924.396484,937.091797 L927.428711,937.091797 L927.428711,939.772461 L927.487305,939.772461 C927.985352,938 929.450195,936.930664 931.325195,936.930664 C931.793945,936.930664 932.189453,936.974609 932.438477,937.033203 L932.438477,940.006836 C932.174805,939.904297 931.618164,939.816406 930.988281,939.816406 C928.893555,939.816406 927.575195,941.266602 927.575195,943.507812 L927.575195,953 L924.396484,953 Z M939.806641,953.161133 C935.822266,953.161133 933.097656,949.953125 933.097656,945.03125 C933.097656,940.138672 935.822266,936.930664 939.777344,936.930664 C942.0625,936.930664 943.878906,937.970703 944.787109,939.728516 L944.860352,939.728516 L944.860352,930.910156 L948.024414,930.910156 L948.024414,953 L944.948242,953 L944.948242,950.304688 L944.889648,950.304688 C943.952148,952.106445 942.135742,953.161133 939.806641,953.161133 Z M940.612305,939.625977 C938.048828,939.625977 936.349609,941.764648 936.349609,945.045898 C936.349609,948.341797 938.03418,950.46582 940.612305,950.46582 C943.161133,950.46582 944.875,948.297852 944.875,945.045898 C944.875,941.808594 943.161133,939.625977 940.612305,939.625977 Z M953.708008,953.161133 C952.638672,953.161133 951.789062,952.311523 951.789062,951.242188 C951.789062,950.158203 952.638672,949.323242 953.708008,949.323242 C954.791992,949.323242 955.626953,950.158203 955.626953,951.242188 C955.626953,952.311523 954.791992,953.161133 953.708008,953.161133 Z"/>
11
+ </g>
12
+ </svg>
@@ -1,8 +1,8 @@
1
1
  module AttrKeyring
2
2
  module ActiveRecord
3
3
  module ClassMethods
4
- def attr_keyring(keyring)
5
- self.keyring = Keyring.new(keyring)
4
+ def attr_keyring(keyring, encryptor: Encryptor::AES128CBC)
5
+ self.keyring = Keyring.new(keyring, encryptor)
6
6
  end
7
7
 
8
8
  def attr_encrypt(*attributes)
@@ -0,0 +1,32 @@
1
+ module AttrKeyring
2
+ module Encryptor
3
+ class AES
4
+ def self.build_cipher
5
+ OpenSSL::Cipher.new(cipher_name)
6
+ end
7
+
8
+ def self.key_size
9
+ @key_size ||= build_cipher.key_len
10
+ end
11
+
12
+ def self.encrypt(key, message)
13
+ cipher = build_cipher
14
+ cipher.encrypt
15
+ iv = cipher.random_iv
16
+ cipher.iv = iv
17
+ cipher.key = key
18
+ iv + cipher.update(message) + cipher.final
19
+ end
20
+
21
+ def self.decrypt(key, message)
22
+ cipher = build_cipher
23
+ cipher.decrypt
24
+ iv = message[0...cipher.iv_len]
25
+ encrypted = message[cipher.iv_len..-1]
26
+ cipher.iv = iv
27
+ cipher.key = key
28
+ cipher.update(encrypted) + cipher.final
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module AttrKeyring
2
+ module Encryptor
3
+ class AES128CBC < AES
4
+ def self.cipher_name
5
+ "AES-128-CBC"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module AttrKeyring
2
+ module Encryptor
3
+ class AES256CBC < AES
4
+ def self.cipher_name
5
+ "AES-256-CBC"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -2,8 +2,9 @@ module AttrKeyring
2
2
  class Key
3
3
  attr_reader :id, :value
4
4
 
5
- def initialize(id, value)
5
+ def initialize(id, value, key_size)
6
6
  @id = Integer(id)
7
+ @key_size = key_size
7
8
  @value = decode(value)
8
9
  end
9
10
 
@@ -13,7 +14,7 @@ module AttrKeyring
13
14
  alias_method :inspect, :to_s
14
15
 
15
16
  private def decode(secret)
16
- return secret if secret.bytesize == 16
17
+ return secret if secret.bytesize == @key_size
17
18
 
18
19
  value = begin
19
20
  Base64.strict_decode64(secret)
@@ -21,9 +22,9 @@ module AttrKeyring
21
22
  Base64.decode64(secret)
22
23
  end
23
24
 
24
- return value if value.bytesize == 16
25
+ return value if value.bytesize == @key_size
25
26
 
26
- raise InvalidSecret, "Secret must be 16 bytes, instead got #{value.bytesize}"
27
+ raise InvalidSecret, "Secret must be #{@key_size} bytes, instead got #{value.bytesize}"
27
28
  end
28
29
  end
29
30
  end
@@ -1,10 +1,9 @@
1
1
  module AttrKeyring
2
2
  class Keyring
3
- CIPHER_NAME = "AES-128-CBC".freeze
4
-
5
- def initialize(keyring)
3
+ def initialize(keyring, encryptor = Encryptor::AES128CBC)
4
+ @encryptor = encryptor
6
5
  @keyring = keyring.map do |id, value|
7
- Key.new(id, value)
6
+ Key.new(id, value, @encryptor.key_size)
8
7
  end
9
8
  end
10
9
 
@@ -20,7 +19,7 @@ module AttrKeyring
20
19
  end
21
20
 
22
21
  def []=(id, value)
23
- @keyring << Key.new(id, value)
22
+ @keyring << Key.new(id, value, @encryptor.key_size)
24
23
  end
25
24
 
26
25
  def clear
@@ -28,24 +27,11 @@ module AttrKeyring
28
27
  end
29
28
 
30
29
  def encrypt(message, keyring_id = current_key.id)
31
- cipher = OpenSSL::Cipher.new(CIPHER_NAME)
32
- cipher.encrypt
33
- iv = cipher.random_iv
34
- cipher.iv = iv
35
- cipher.key = self[keyring_id].value
36
- iv + cipher.update(message) + cipher.final
30
+ @encryptor.encrypt(self[keyring_id].value, message)
37
31
  end
38
32
 
39
- def decrypt(secret, keyring_id)
40
- decipher = OpenSSL::Cipher.new(CIPHER_NAME)
41
- decipher.decrypt
42
-
43
- iv = secret[0...decipher.iv_len]
44
- encrypted = secret[decipher.iv_len..-1]
45
-
46
- decipher.iv = iv
47
- decipher.key = self[keyring_id].value
48
- decipher.update(encrypted) + decipher.final
33
+ def decrypt(message, keyring_id)
34
+ @encryptor.decrypt(self[keyring_id].value, message)
49
35
  end
50
36
  end
51
37
  end
@@ -1,3 +1,3 @@
1
1
  module AttrKeyring
2
- VERSION = "0.1.1".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
data/lib/attr_keyring.rb CHANGED
@@ -6,6 +6,9 @@ module AttrKeyring
6
6
  require "attr_keyring/active_record"
7
7
  require "attr_keyring/keyring"
8
8
  require "attr_keyring/key"
9
+ require "attr_keyring/encryptor/aes"
10
+ require "attr_keyring/encryptor/aes_128_cbc"
11
+ require "attr_keyring/encryptor/aes_256_cbc"
9
12
 
10
13
  UnknownKey = Class.new(StandardError)
11
14
  InvalidSecret = Class.new(StandardError)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_keyring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-02 00:00:00.000000000 Z
11
+ date: 2018-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -139,10 +139,15 @@ files:
139
139
  - README.md
140
140
  - Rakefile
141
141
  - attr_keyring.gemspec
142
+ - attr_keyring.png
143
+ - attr_keyring.svg
142
144
  - bin/console
143
145
  - bin/setup
144
146
  - lib/attr_keyring.rb
145
147
  - lib/attr_keyring/active_record.rb
148
+ - lib/attr_keyring/encryptor/aes.rb
149
+ - lib/attr_keyring/encryptor/aes_128_cbc.rb
150
+ - lib/attr_keyring/encryptor/aes_256_cbc.rb
146
151
  - lib/attr_keyring/key.rb
147
152
  - lib/attr_keyring/keyring.rb
148
153
  - lib/attr_keyring/version.rb