sym 0.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +25 -0
  3. data/.document +2 -0
  4. data/.gitignore +6 -2
  5. data/.rspec +1 -1
  6. data/.rubocop.yml +1156 -0
  7. data/.travis.yml +10 -2
  8. data/.yardopts +5 -0
  9. data/Gemfile +2 -0
  10. data/LICENSE +22 -0
  11. data/MANAGING-KEYS.md +67 -0
  12. data/README.md +444 -12
  13. data/Rakefile +10 -2
  14. data/bin/sym.bash-completion +24 -0
  15. data/exe/keychain +38 -0
  16. data/exe/sym +20 -0
  17. data/lib/sym.rb +110 -2
  18. data/lib/sym/app.rb +56 -0
  19. data/lib/sym/app/args.rb +42 -0
  20. data/lib/sym/app/cli.rb +192 -0
  21. data/lib/sym/app/commands.rb +56 -0
  22. data/lib/sym/app/commands/command.rb +77 -0
  23. data/lib/sym/app/commands/delete_keychain_item.rb +17 -0
  24. data/lib/sym/app/commands/encrypt_decrypt.rb +26 -0
  25. data/lib/sym/app/commands/generate_key.rb +37 -0
  26. data/lib/sym/app/commands/open_editor.rb +97 -0
  27. data/lib/sym/app/commands/print_key.rb +15 -0
  28. data/lib/sym/app/commands/show_examples.rb +76 -0
  29. data/lib/sym/app/commands/show_help.rb +16 -0
  30. data/lib/sym/app/commands/show_language_examples.rb +81 -0
  31. data/lib/sym/app/commands/show_version.rb +14 -0
  32. data/lib/sym/app/input/handler.rb +41 -0
  33. data/lib/sym/app/keychain.rb +135 -0
  34. data/lib/sym/app/nlp.rb +18 -0
  35. data/lib/sym/app/nlp/constants.rb +32 -0
  36. data/lib/sym/app/nlp/translator.rb +61 -0
  37. data/lib/sym/app/nlp/usage.rb +72 -0
  38. data/lib/sym/app/output.rb +15 -0
  39. data/lib/sym/app/output/base.rb +61 -0
  40. data/lib/sym/app/output/file.rb +18 -0
  41. data/lib/sym/app/output/noop.rb +14 -0
  42. data/lib/sym/app/output/stdout.rb +13 -0
  43. data/lib/sym/app/password/cache.rb +63 -0
  44. data/lib/sym/app/private_key/base64_decoder.rb +17 -0
  45. data/lib/sym/app/private_key/decryptor.rb +71 -0
  46. data/lib/sym/app/private_key/detector.rb +42 -0
  47. data/lib/sym/app/private_key/handler.rb +44 -0
  48. data/lib/sym/app/short_name.rb +10 -0
  49. data/lib/sym/application.rb +114 -0
  50. data/lib/sym/cipher_handler.rb +46 -0
  51. data/lib/sym/configuration.rb +39 -0
  52. data/lib/sym/data.rb +23 -0
  53. data/lib/sym/data/decoder.rb +28 -0
  54. data/lib/sym/data/encoder.rb +24 -0
  55. data/lib/sym/data/wrapper_struct.rb +43 -0
  56. data/lib/sym/encrypted_file.rb +34 -0
  57. data/lib/sym/errors.rb +37 -0
  58. data/lib/sym/extensions/class_methods.rb +12 -0
  59. data/lib/sym/extensions/instance_methods.rb +114 -0
  60. data/lib/sym/version.rb +1 -1
  61. data/sym.gemspec +34 -15
  62. metadata +224 -9
data/.travis.yml CHANGED
@@ -1,5 +1,13 @@
1
- sudo: false
2
1
  language: ruby
2
+ env:
3
+ - CODECLIMATE_REPO_TOKEN=be1a1a266b0ffc81fa0bd1e432a229f2a4ab420dcb9e9e15c1e75e2acad573b7
3
4
  rvm:
5
+ - 2.2.5
4
6
  - 2.3.1
5
- before_install: gem install bundler -v 1.13.5
7
+ script: "rake"
8
+ notifications:
9
+ email:
10
+ recipients:
11
+ - kigster@gmail.com
12
+ on_success: change
13
+ on_failure: always
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+
2
+ --protected
3
+ --no-private
4
+ --embed-mixin ClassMethods
5
+ --embed-mixin Sym::Extensions::InstanceMethods
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in sym.gemspec
4
4
  gemspec
5
+
6
+ gem 'ffi', :platforms => [:mswin, :mingw]
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright © 2016 Konstantin Gredeskoul, all rights reserved.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/MANAGING-KEYS.md ADDED
@@ -0,0 +1,67 @@
1
+ # Managing Private Keys
2
+
3
+ In this document we discuss several methods of keeping the private keys safe and yet conveniently available when needed. We also note the possible security implications of each method.
4
+
5
+ We assume that you have some data or files that have been previously encrypted with a 32-byte key using this library, and that you want to be able to access the data easily with your private key, but at the same time not make it too easy for an attacker to find the keys.
6
+
7
+ ## Method 1.<br>Keychain Access on Mac OS-X
8
+
9
+ How you store the secret, is up to you, but here is one way that leverages Mac OS-X Keychain. In fact you can store multiple keys if you like. In the example below we'll store two separate keys, one for staging and one for production:
10
+
11
+ In your terminal, type these two commands. Note that the `-s` parameter is something you might want to customize, and make it easy to find. For example, instead of using `production` you could use `big-corp-django-secret-production`. The name should be such that it's easy to find once you open KeyChain Editor later.
12
+
13
+ ```bash
14
+ security add-generic-password -a $USER -D "secret-cipher-base64" -s "staging"
15
+ security add-generic-password -a $USER -D "secret-cipher-base64" -s "production"
16
+ ```
17
+
18
+ This step does not actually store any key, it simply creates a KeyChain placeholder for it. We'll generate and add the key next.
19
+
20
+ Finally, to make this a bit more efficient, I recommend listing the key names in an array-type environment variable set in your `~/.bashrc` file, for example:
21
+
22
+ ```bash
23
+ # ~/.bashrc
24
+ declare -a secret_names=(production staging)
25
+ ```
26
+
27
+ After declaring this array, you can even rewrite the above command as a loop, which could be handy if you are storing not 2 or 3 but 10+ keys.
28
+
29
+ ```bash
30
+ for secret_name in ${secret_names[@]}; do
31
+ security add-generic-password -a $USER \
32
+ -D "secret-cipher-base64" -s $secret_name
33
+ done
34
+ ```
35
+
36
+ ### Saving the Secret to KeyChain
37
+
38
+ * Open `KeyChain Access` application
39
+ * Search for the token you specified, for example `production`
40
+ * Double-click on the matching entry
41
+ * Click "Show password"
42
+ * Paste the copied value in that field
43
+ * Click "Save Changes"
44
+ * Repeat for `staging` or any other key you want to save.
45
+
46
+ ### Retrieving Secret from the KeyChain
47
+
48
+ Using the below bash function, you can retrieve and export the sym as environment variables, which can later be read by your code:
49
+
50
+ ```bash
51
+ # append this function to your ~/.bashrc or ~/.bash_profile
52
+ function load_keys() {
53
+ declare -a secret_names=(production staging)
54
+ for secret_name in ${secret_names[@]}; do
55
+ varname="secret_${secret_name}" # eg, $secret_production
56
+ secret=`security find-generic-password -g -a $USER -w -D "secret-cipher-base64" -s "$secret_name"`
57
+ eval "export $varname=$secret"
58
+ done
59
+ }
60
+ ```
61
+
62
+ With this out of the way, we just need to type `load_keys` in Terminal to get our keys automatically exported.
63
+
64
+ ### Security
65
+
66
+ In this model, an attacker who obtains login access to your account will be able to quickly examine the local environment to discover one or more private keys already exported.
67
+
data/README.md CHANGED
@@ -1,28 +1,440 @@
1
- # Sym
2
1
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sym`. To experiment with that code, run `bin/console` for an interactive prompt.
2
+ # Sym Your Encryption Best Friend
4
3
 
5
- TODO: Delete this and the text above, and describe your gem
4
+ [![Gem Version](https://badge.fury.io/rb/sym.svg)](https://badge.fury.io/rb/sym)
5
+ [![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/sym?type=total)](https://rubygems.org/gems/sym)
6
+ [![Documentation](http://inch-ci.org/github/kigster/sym.png)](http://inch-ci.org/github/kigster/sym)
7
+
8
+ [![Build Status](https://travis-ci.org/kigster/sym.svg?branch=master)](https://travis-ci.org/kigster/sym)
9
+ [![Code Climate](https://codeclimate.com/github/kigster/secrets-cipher-base64/badges/gpa.svg)](https://codeclimate.com/github/kigster/secrets-cipher-base64)
10
+ [![Test Coverage](https://codeclimate.com/github/kigster/secrets-cipher-base64/badges/coverage.svg)](https://codeclimate.com/github/kigster/secrets-cipher-base64/coverage)
11
+ [![Issue Count](https://codeclimate.com/github/kigster/secrets-cipher-base64/badges/issue_count.svg)](https://codeclimate.com/github/kigster/secrets-cipher-base64)
12
+
13
+
14
+ ## Description
15
+
16
+ ### Summary
17
+
18
+ > __sym__ is little program that makes it _trivial to encrypt and decrypt sensitive data_. But, unlike many other existing tools, __sym__'s goal is to dramatically simplify the command line interface (CLI), and make symmetric encryption as routine as listing directories in Terminal.
19
+
20
+ With this tool I wanted to make it easy to memorize the most common options, so that there is little no longer a barrier to the full power of encryption offered by [`OpenSSL`](https://www.openssl.org/) library.
21
+
22
+ And no tool works in isolation: this is just a stepping stone that could be part of your deployment or infrastructure code: don't rely on external services: minimize the risk of a "man-in-the-middle" attack, by dealing with the encryption and decryption locally. Ideal application of this gem, is the ability to store sensitive application _secrets_ protected on a file system, or in a repo, and use `sym` to automaticaly decrypt the data when any changes are to be made, or when the data needs to be read by an application service.
23
+
24
+ And finally, in addition to the rich CLI interface of the `sym` executable, there is a rich and extensibe symmetric encryption API that can be easily used from any ruby project.
25
+
26
+ ### How It Works
27
+
28
+ 1. You start with a piece of sensitive data, say it's called _X_.
29
+ 2. _X_ is currently a file on your file system, unencrypted.
30
+ 2. You use __sym__ (with `-g` — for "generate") to make a new encryption key. The key is 256 bits, or 32 bytes, or 45 bytes when base64-encoded.
31
+ 3. You must save this key somewhere safe. We'll talk about this further.
32
+ 4. You use __sym__ (with `-e`) to encrypt _X_ with the key, and save into _Y_.
33
+ 5. You now delete _X_ from your file system. You now only have _Y_ and the _key_.
34
+ 7. To read the data back, you use __sym__ with the `-d` (for "decrypt") to decrypt _Y_ back. You can print the contents or save it again.
35
+ 8. But, instead of just decrypting it, you can use the `-t` mode (for "ediT"), which would decrypt _Y_ into _X_, save _X_ into a temporary location, and allow you to edit the unencrypted file using `$EDITOR`. Once you save and exit the editor, a new version is automatically encrypted and replaces the old version, showing you the diff and, optionally, creating a backup.
36
+
37
+ ### Features
38
+
39
+ The `sym` executable as well as the Ruby API provide:
40
+
41
+ * Symmetric data encryption with:
42
+ * the cipher `AES-256-CBC` used by the US Government
43
+ * 256-bit private key
44
+ * which can be auto-generated, and is a *base64-encoded* string which is 45 characters long. The *decoded* secret is always 32 characters long (or 256 bytes long).
45
+ * which can be optionally password-encrypted using 128-bit key.
46
+ * which is automatically detected when the key is read
47
+ * Rich command line interface with some innovative features, such as inline editing of an encrypted file, using your favorite `$EDITOR`.
48
+ * Data handling:
49
+ * Automatic compression of the data upon encryption
50
+ * Automatic base64 encryption to make all encrypted strings fit onto a single line.
51
+ * This makes the format suitable for YAML or JSON configuration files, where only the values are encrypted.
52
+ * Rich Ruby API
53
+ * (OS-X Only): Ability to create, add and delete generic password entries from the Mac OS-X KeyChain, and to leverage the KeyChain to store sensitive private keys.
54
+
55
+ ### Symmetric Encryption
56
+
57
+ Symmetric encryption simply means that we are using the same private key to encrypt and decrypt.
58
+ In addition to the private key, the encryption uses an IV vector. The library completely hides `iv` from the user, generates one random `iv` per encryption, and stores it together with the field itself (*base64-encoded*).
6
59
 
7
60
  ## Installation
8
61
 
9
- Add this line to your application's Gemfile:
62
+ If you plan on using the library in your ruby project with Bundler managing its dependencies, just include the following line in your `Gemfile`:
63
+
64
+ gem 'sym'
65
+
66
+ And then run `bundle`.
67
+
68
+ Or install it into the global namespace with `gem install` command:
69
+
70
+ $ gem install sym
71
+ $ sym -h
72
+ $ sym -E # see examples
73
+
74
+ ### BASH Completion (Optional Step)
75
+
76
+ After gem installation, an message will tell you to install a shown BASH script to your `~/.bashrc` or equivalent.
77
+
78
+ Should you choose to install it (this part is optional), you will be able to use "tab-tab" after typing `sym` and you'll be able to choose from all supported flags.
79
+
80
+ ## Usage
81
+
82
+ ### Private Keys
83
+
84
+ This library relies on the existance of the 32-byte private key (aka, *a secret*) to perform encryption and decryption.
85
+
86
+ The key can be easily:
87
+
88
+ * generated by this gem and displayed, copied to the clipboard, or saved to the KeyChain
89
+ * one way or another must be kept very well protected and secure from attackers
90
+ * can be fetched from the the Keychain in subsequent encryption/decryption steps
91
+ * password-protected, which you can enable during the generation with the `-p` flag.
92
+ * NOTE: right now there is no way to add a password to an existing key, only generate a new one.
93
+
94
+ Unencrypted private key will be in the form of a base64-encoded string, 45 characters long.
95
+
96
+ Encrypted private key will be considerably longer, perhaps 200-300 characters long.
97
+
98
+ When the private key is encrypted, `sym` will request the password every time it is used. We are looking at adding a caching layer with a configuerable timeout, so that the password is only re-entered once per given period.
99
+
100
+ ### Command Line (CLI)
101
+
102
+ You can generate using the command line, or in a programmatic way. First we'll discuss the command line usage, and in a later section we'll discuss Ruby API provided by the gem.
103
+
104
+ #### Generating and Using Private Keys
105
+
106
+ Once the gem is installed you will be able to run an executable `sym`. Now let's generate and copy the new private key to the clipboard. Clipboard copy is activated with the -c flag:
107
+
108
+ sym -gc
109
+
110
+ Or save a new key into a bash variable
111
+
112
+ SECRET=$(sym -g)
113
+
114
+ Or save it to a file:
115
+
116
+ sym -go ~/.key
117
+
118
+ Or create a password-protected key, and save it to a file:
119
+
120
+ sym -gcp -o ~/.secret
121
+ # New Password: ••••••••••
122
+ # Confirm Password: ••••••••••
123
+
124
+ You can subsequently use the private key by either:
125
+
126
+ 1. passing the `-k [key value]` flag
127
+ 2. passing the `-K [key file]` flag3.
128
+ 3. pasting or typing the key with the `-i` (interactive) flag
129
+ 4. passing the `-x [keychain access entry name]` flag to read from Mac OS-X KeyChain Access's generic password field.
130
+
131
+ #### Using KeyChain Access on Mac OS-X
132
+
133
+ On Mac OS-X there is a third option – using the Keychain Access Manager behind the scenes. Apple released a `security` command line tool, which this library uses to securely store a key/value pair of the key name and the actual private key in your OS-X KeyChain. The advantages of this method are numerous:
134
+
135
+ * The private key won't be lying around your file system unencrypted, so if your Mac is ever stolen, you don't need to worry about the keys running wild.
136
+ * If you sync your keychain with iCloud you will have access to it on other machines
137
+
138
+ To activate the KeyChain mode on the Mac, use `-x <keyname>` field instead of `-k` or `-K`, and add it to `-g` when generating a key. The `keyname` is what you name this particular key base on where it's going to be used. For example, you may call it `staging`, etc.
139
+
140
+ The following command generates the private key and immediately stores it in the KeyChain access under the name provided:
141
+
142
+ sym -g -x staging
143
+
144
+ Now, whenever you need to encrypt something, in addition to the `-k` and `-K` you can also choose `-x staging`. This will retrieve the key from the KeyChain access, and use it for encryption/decryption.
145
+
146
+ Finally, you can delete a key from KeyChain access by running:
147
+
148
+ sym --keychain-del staging
149
+
150
+ #### KeyChain Key Management
151
+
152
+ Another tiny executable supplied with this library is called `keychain`
153
+
154
+ ```bash
155
+ Usage: keychain item [ add <contents> | find | delete ]
156
+ ```
157
+ You can use this to add an existing key that can be used with the `sym` later. Of course you can also use the tool to find or delete it.
158
+
159
+ #### Encryption and Decryption
160
+
161
+ This may be a good time to take a look at the full help message for the `sym` tool, shown naturally with a `-h` or `--help` option.
162
+
163
+ ```
164
+ Sym (1.7.0) – encrypt/decrypt data with a private key
165
+
166
+ Usage:
167
+ # Generate a new key:
168
+ sym -g [ -c ] [ -p ] [ -x keychain ] [ -o keyfile | -q | ]
169
+
170
+ # Encrypt/Decrypt
171
+ sym [ -d | -e ] [ -f <file> | -s <string> ]
172
+ [ -k key | -K keyfile | -x keychain | -i ]
173
+ [ -o <output file> ]
174
+
175
+ # Edit an encrypted file in $EDITOR
176
+ sym -t -f <file> [ -b ][ -k key | -K keyfile | -x keychain | -i ]
177
+
178
+ Modes:
179
+ -e, --encrypt encrypt mode
180
+ -d, --decrypt decrypt mode
181
+ -t, --edit decrypt, open an encr. file in an $EDITOR
182
+
183
+ Create a private key:
184
+ -g, --generate generate a new private key
185
+ -p, --password encrypt the key with a password
186
+ -c, --copy copy the new key to the clipboard
187
+ -x, --keychain [key-name] add to (or read from) the OS-X Keychain
188
+
189
+ Password Caching:
190
+ -M, --password-timeout [timeout] when passwords expire (in seconds)
191
+ -P, --no-password-cache disables key password caching
192
+
193
+ Provide a private key:
194
+ -i, --interactive Paste or type the key interactively
195
+ -k, --private-key [key] private key as a string
196
+ -K, --keyfile [key-file] private key from a file
197
+
198
+ Data:
199
+ -s, --string [string] specify a string to encrypt/decrypt
200
+ -f, --file [file] filename to read from
201
+ -o, --output [file] filename to write to
202
+
203
+ Flags:
204
+ --keychain-del [key-name] delete keychain entry with that name
205
+ -b, --backup create a backup file in the edit mode
206
+ -v, --verbose show additional information
207
+ -T, --trace print a backtrace of any errors
208
+ -q, --quiet silence all output
209
+ -V, --version print library version
210
+ -N, --no-color disable color output
211
+
212
+ Help & Examples:
213
+ -E, --examples show several examples
214
+ -L, --language natural language examples
215
+ -h, --help show help
216
+ ```
217
+
218
+ ### CLI Usage Examples
219
+
220
+ __Generating the Key__:
221
+
222
+ Generate a new private key into an environment variable:
223
+
224
+ export KEY=$(sym -g)
225
+ echo $KEY
226
+ # => 75ngenJpB6zL47/8Wo7Ne6JN1pnOsqNEcIqblItpfg4=
227
+
228
+ Generate a new password-protected key, copy to the clipboard & save to a file:
229
+
230
+ sym -gpc -o ~/.key
231
+ New Password : ••••••••••
232
+ Confirm Password : ••••••••••
233
+
234
+ Encrypt a plain text string with a key, and save the output to a file:
235
+
236
+ sym -e -s "secret string" -k $KEY -o file.enc
237
+ cat file.enc
238
+ # => Y09MNDUyczU1S0UvelgrLzV0RTYxZz09CkBDMEw4Q0R0TmpnTm9md1QwNUNy%T013PT0K
239
+
240
+ Decrypt a previously encrypted string:
241
+
242
+ sym -d -s $(cat file.enc) -k $KEY
243
+ # => secret string
244
+
245
+ Encrypt a file and save it to sym.enc:
246
+
247
+ sym -e -f app-sym.yml -o app-sym.enc -k $KEY
248
+
249
+ Decrypt an encrypted file and print it to STDOUT:
250
+
251
+ sym -df app-sym.enc -k $KEY
252
+
253
+ ##### Inline Editing
254
+
255
+ The `sym` CLI tool supports one interesting mode where you can open an encrypted file in an `$EDITOR`, and edit it's unencrypted version (stored temporarily in a temp file), and upon saving and exiting the gem will automatically diff the new and old content, and if different – will save encrypt it and overwrite the original file.
256
+
257
+ In this mode several flags are of importance:
258
+
259
+ -b (--backup) – will create a backup of the original file
260
+ -v (--verbose) - will show additional info about file sizes
261
+
262
+ Here is a full command that opens a file specified by `-f | --file`, using the key specified in `-K | --keyfile`, in the editor defined by the `$EDITOR` environment variable (or if not set – defaults to `/bin/vi`)".
263
+
264
+ NOTE: while much effort has been made to ensure that the gem is bug free, the reality is that no software is bug free. Please make sure to backup your encrypted file before doing it for the first few times to get familiar with the command.
265
+
266
+ To edit an encrypted file in $EDITOR, while asking to paste the key (`-i | --interactive`), while creating a backup file (`-b | --backup`):
267
+
268
+ sym -tibf data.enc
269
+ # => Private Key: ••••••••••••••••••••••••••••••••••••••••••••
270
+ #
271
+ # => Diff:
272
+ # 3c3
273
+ # # (c) 2015 Konstantin Gredeskoul. All rights reserved.
274
+ # ---
275
+ # # (c) 2016 Konstantin Gredeskoul. All rights reserved.
276
+
277
+
278
+ ### Natural Language Processing
279
+
280
+ When sym is invoked, and the first argument does not begin with a dash,
281
+ then the the NLP (natural language processing) Translator is invoked.
282
+ The Translator is based on a very simple algorithm:
283
+
284
+ * ignore any of the words tagged STRIPPED. These are the ambiguous words, or words with duplicate meaning.
285
+ * map the remaining arguments to regular double-dashed options using the DICTIONARY
286
+ * words that are a direct match for a --option are automatically double-dashed
287
+ * remaining words are left as is (these would be file names, key names, etc).
288
+ * finally, the resulting "new" command line is parsed with regular options.
289
+ * When arguments include "verbose", NLP system will print "before" and "after"
290
+ of the arguments, so that any issues can be debugged and corrected.
291
+
292
+ #### CURRENTLY IGNORED WORDS:
293
+
294
+ and, a, the, it, item, to, key, with, about, for, of, new, make, store, in, print
295
+
296
+ #### REGULAR WORD MAPPING
297
+
298
+ ```
299
+ ________________________________________________________________________
300
+ clipboard ───────➤ --copy
301
+ unlock ───────➤ --decrypt
302
+ open ───────➤ --edit
303
+ lock ───────➤ --encrypt
304
+ ───────➤ --backup
305
+ ───────➤ --keychain
306
+ read ───────➤ --file
307
+ create ───────➤ --generate
308
+ ask enter type ───────➤ --interactive
309
+ from ───────➤ --keyfile
310
+ save write ───────➤ --output
311
+ using private ───────➤ --private_key
312
+ value ───────➤ --string
313
+ silently quietly silent sym ───────➤ --quiet
314
+ secure secured protected ───────➤ --password
315
+ ________________________________________________________________________
316
+ ```
317
+
318
+ #### EXAMPLES
319
+
320
+ ```bash
321
+ # generate a new private key and copy to the clipboard but do not print to terminal
322
+ sym create new key to clipboard quietly
323
+
324
+ # generate and save to a file a password-protected key, silently
325
+ sym create a secure key and save it to "my.key"
326
+
327
+ # encrypt a plain text string with a key, and save the output to a file
328
+ sym encrypt string "secret string" using $(cat my.key) save to file.enc
329
+
330
+ # decrypt a previously encrypted string:
331
+ sym decrypt string $ENC using $(cat my.key)
332
+
333
+ # encrypt "file.txt" with key from my.key and save it to file.enc
334
+ sym encrypt file file.txt with key from my.key and save it to file.enc
335
+
336
+ # decrypt an encrypted file and print it to STDOUT:
337
+ sym decrypt file file.enc with key from "my.key"
338
+
339
+ # edit an encrypted file in $EDITOR, ask for key, and create a backup upon save
340
+ sym edit file file.enc ask for a key and make a backup
341
+
342
+ # generate a new password-encrypted key, save it to your Keychain:
343
+ sym create a new protected key store in keychain "my-keychain-key"
344
+
345
+ # print the key stored in the keychain item "my-keychain-key"
346
+ sym print keychain "my-keychain-key"
347
+
348
+ # use the new key to encrypt a file:
349
+ sym encrypt with keychain "my-keychain-key" file "password.txt" and write to "passwords.enc"
350
+ ```
351
+
352
+ ### Ruby API
353
+
354
+ To use this library you must include the main `Sym` module into your library.
355
+
356
+ Any class including `Sym` will be decorated with new class methods `#private_key` and `#create_private_key`, as well as instance methods `#encr`, and `#decr`.
357
+
358
+ `#create_private_key` will generate a new key each time it's called, while `#private_key` will either assign an existing key (if a value is passed), or generate and save a new key in the class instance variable. Therefore each class including `Sym` will use it's own key (unless the key is assigned).
359
+
360
+ The following example illustrates this point:
10
361
 
11
362
  ```ruby
12
- gem 'sym'
363
+ require 'sym'
364
+
365
+ class TestClass
366
+ include Sym
367
+ end
368
+ @key = TestClass.create_private_key
369
+ @key.eql?(TestClass.private_key) # => false
370
+ # A new key was created and saved in #private_key accessor.
371
+
372
+ class SomeClass
373
+ include Sym
374
+ private_key TestClass.private_key
375
+ end
376
+
377
+ @key.eql?(SomeClass.private_key) # => true (it was assigned)
13
378
  ```
14
379
 
15
- And then execute:
380
+ #### Encryption and Decryption
16
381
 
17
- $ bundle
382
+ So how would we use this library from another ruby project to encrypt and decrypt values?
18
383
 
19
- Or install it yourself as:
384
+ After including the `Sym` module in a ruby class, the class will now have the `#encr` and `#decr` instance methods, as well as `#secret` and `#create_private_key class methods.
20
385
 
21
- $ gem install sym
386
+ Therefore you could write something like this below, protecting a sensitive string using a class-level secret.
22
387
 
23
- ## Usage
388
+ ```ruby
389
+ require 'sym'
390
+ class TestClass
391
+ include Sym
392
+ private_key ENV['SECRET']
393
+
394
+ def sensitive_value=(value)
395
+ @sensitive_value = encr(value, self.class.private_key)
396
+ end
397
+ def sensitive_value
398
+ decr(@sensitive_value, self.class.private_key)
399
+ end
400
+ end
401
+ ```
402
+
403
+ #### Full Application API
404
+
405
+ Since the command line interface offers more than just encryption/decryption, it is available via `Sym::Application` class.
406
+
407
+ The class is instantiated with a hash that would be otherwise generated by `Slop.parse(argv)` – ie, typical `options`.
408
+
409
+ Here is an example:
410
+
411
+ ```ruby
412
+ require 'sym/application'
413
+
414
+ key = Sym::Application.new(generate: true).execute
415
+ # => returns a new private key
416
+ ```
417
+
418
+ ### Configuration
419
+
420
+ The library offers a typical `Sym::Configuration` class which can be used to tweak some of the internals of the gem. This is really meant for a very advanced user who knows what she is doing. The following snippet is actually part of the Configuration class itself, but can be overridden by your code that uses and initializes this library. `Configuration` is a singleton, so changes to it will propagate to any subsequent calls to the gem.
421
+
422
+ ```ruby
423
+ require 'zlib'
424
+ Sym::Configuration.configure do |config|
425
+ config.password_cipher = 'AES-128-CBC' #
426
+ config.data_cipher = 'AES-256-CBC'
427
+ config.private_key_cipher = config.data_cipher
428
+ config.compression_enabled = true
429
+ config.compression_level = Zlib::BEST_COMPRESSION
430
+ end
431
+ ```
432
+
433
+ As you can see, it's possible to change the default cipher typem, although not all ciphers will be code-compatible with the current algorithm, and may require additional code changes.
24
434
 
25
- TODO: Write usage instructions here
435
+ ## Managing Keys
436
+
437
+ There is a separate discussion about ways to securely store private keys in [MANAGING-KEYS.md](https://github.com/kigster/sym/blob/master/MANAGING-KEYS.md).
26
438
 
27
439
  ## Development
28
440
 
@@ -32,5 +444,25 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
444
 
33
445
  ## Contributing
34
446
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sym.
447
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kigster/sym.
448
+
449
+ ## Feature Ideas
450
+
451
+ ### Natural Language Based API
452
+
453
+ This is the proposed mini-idea/specification for an alternative CLI that is at a feature parity with the standard flag-based CLI.
454
+
455
+ sym generate key to the clipboard and keychain
456
+ sym encrypt file 'hello' using $key [to output.enc]
457
+ sym edit 'passwords.enc' using $key
458
+ sym decrypt /etc/secrets encrypted with $key save to ./secrets
459
+ sym encrypt with keychain $item file $input
460
+
461
+ ## License
462
+
463
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
464
+
465
+ ## Author
466
+
467
+ This library is the work of [Konstantin Gredeskoul](http:/kig.re), &copy; 2016, distributed under the MIT license.
36
468