1 | salty
|
2 | =====
|
3 |
|
4 | Alternative public key encryption
|
5 |
|
6 | ## Description
|
7 |
|
8 | Salty is an alternative to PGP/GPG using [NaCl](https://en.wikipedia.org/wiki/NaCl_(software)) instead of RSA/DSA.
|
9 |
|
10 | Commits and tags in this repo are signed with GPG key [5FBB 2F98 3862 1AFF](https://keybase.io/carlos8f).
|
11 |
|
12 | ### Features
|
13 |
|
14 | - NO [3rd parties](https://peerio.com/pricing.html), NO [p2p network](https://en.wikipedia.org/wiki/PRISM_(surveillance_program)), NO [browser js](https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/), NO [package managers](https://docs.npmjs.com/misc/scripts), NO [exotic/compiled deps](https://www.openssl.org/news/vulnerabilities.html), and NO [shady corporations](https://github.com/VirgilSecurity). PERIOD.
|
15 | - general purpose CLI, lightweight library attached
|
16 | - audited, bundled dependencies - no install scripts or backdoors
|
17 | - supports anonymous-sender or signed/verified messaging
|
18 | - sharable pubkey string that can fit in a single tweet
|
19 | - does NOT use your ssh keys, pgp keys, or anything RSA
|
20 | - encrypt public key is always ephemeral - does NOT leak metadata
|
21 | - sender identity is deniable, unless they explicitly commit to sign the message
|
22 | - file length hidden with padding
|
23 | - public signing/verifying with detached signatures
|
24 | - binary or "ascii armor" PEM output
|
25 | - import/export your wallet folder - PEM encoded and secretboxed with Scrypt KDF
|
26 | - (new in 3.1) can use anonymous private [Github gists](https://gist.github.com/) to remotely store salty messages
|
27 | - (new in 3.1) full tar/gz support for encrypting/decrypting directories (supports symmetric or asymmetric cipher)
|
28 | - MIT-licensed
|
29 |
|
30 | ## Install (Mac OSX)
|
31 |
|
32 | ```
|
33 | $ brew tap carlos8f/tap
|
34 | $ brew install salty
|
35 | ```
|
36 |
|
37 | ## Other UNIX-based platforms:
|
38 |
|
39 | Install first: [nodejs](https://nodejs.org/)
|
40 |
|
41 | ```
|
42 | $ git clone https://github.com/carlos8f/salty.git
|
43 | $ sudo ln -s `pwd`/salty/salty /usr/local/bin/salty
|
44 | ```
|
45 |
|
46 | ## Useful links
|
47 |
|
48 | - [S8F Console: How to use Salty](https://s8f.org/1465282150/) - Basic demonstration of the Salty CLI
|
49 | - [Salty: PGP Evolved](https://s8f.org/1465262642/) - How Salty improves on the PGP model
|
50 |
|
51 | ## Format
|
52 |
|
53 | Byte counts are in `()` parenthesis.
|
54 |
|
55 | ### Salty wallet
|
56 |
|
57 | Designed to allow both decryption and signing.
|
58 |
|
59 | ```
|
60 | decryption signing
|
61 | -------------- + -----------
|
62 | decryptSk (32) signSk (64)
|
63 | ```
|
64 |
|
65 | Example (wallets are stored as encrypted PEM on disk)
|
66 |
|
67 | ```
|
68 | -----BEGIN SALTY WALLET-----
|
69 | Proc-Type: 4,ENCRYPTED
|
70 | DEK-Info: NACL-SCRYPT,IP3NRMw15AGYyU56xwYPVJFa4Xx0aock
|
71 |
|
72 | OjCNhUvjNml3bebBVsIBpTBdvWSRkUG6vVZkdpzFZf9Ak/Bh0ghaXsEhuAiElEMy
|
73 | 2ghCEF5oQVO3dAWdflcvuVH3CSXlPlBfXWr6Y0EEOST3jYwaRS8Qfa2786YNBYCm
|
74 | NBm4au6wbuVp8dL41jhLeQ==
|
75 | -----END SALTY WALLET-----
|
76 | ```
|
77 |
|
78 | ### Salty pubkey
|
79 |
|
80 | Designed to be sharable, human-readable, and unique.
|
81 |
|
82 | ```
|
83 | type public keys optional meta
|
84 | ---------- [space] ----------------------------------------- [space] -------- ---------
|
85 | "salty-id" base64url(encryptPk (32) + verifyPk (32)) "{name}" <{email}>
|
86 |
|
87 | ```
|
88 |
|
89 | Example:
|
90 |
|
91 | ```
|
92 | salty-id jbMGsmaXG7bJLZjhnn_i-9GyQtEVBBTL8JwdpBgKC0y6wvvEbesSYp4vOkjOEt5IZtt0pdrXI2ARZKkAIHUnhg "Carlos Rodriguez" <carlos@s8f.org>
|
93 | ```
|
94 |
|
95 | ### Salty file
|
96 |
|
97 | Designed to allow anonymous or signed messages, and verify message integrity.
|
98 |
|
99 | ```
|
100 | required meta ciphertext
|
101 | -------------- + ----------
|
102 | ephemeral (80) plaintext
|
103 | ```
|
104 |
|
105 | ### Ephemeral
|
106 |
|
107 | Designed to hide the message and header inside an anonymously encrypted/authenticated payload.
|
108 |
|
109 | ```
|
110 | random random message length (encrypted, 24 bytes)
|
111 | -------------- + ---------- + ---------------------------------------
|
112 | encryptPk (32) nonce (24) totalSize (8 bytes, big endian)
|
113 | ```
|
114 |
|
115 | ### Plaintext
|
116 |
|
117 | Appends a header to the message for verification, and pads the plaintext with null bytes.
|
118 |
|
119 | ```
|
120 | --------- + ------- + -------------------
|
121 | message header null bytes (?)
|
122 | ```
|
123 |
|
124 | ### Header
|
125 |
|
126 | Always contains a sha256 HMAC to authenticate the message, and optionally contains a signature from the sender.
|
127 |
|
128 | ```
|
129 | hash: base64( sha256_hmac( shared_secret ) of message )
|
130 | [from-salty-id]: base64(encryptPk (32) + verifyPk (32))
|
131 | [to-salty-id]: base64(encryptPk (32) + verifyPk (32))
|
132 | [signature]: base64( detached sig of previous headers )
|
133 | ```
|
134 |
|
135 | Example:
|
136 |
|
137 | ```
|
138 | hash: dH4McUU9sLJV+i34hfXjSUGTYn2xQhj2gbAYqAMighU=
|
139 | from-salty-id: oU3lbcpdHo81Eo8SifwoHg5CEEZ5q-Rb0_zMWpJU-GWlr9lIjILqv5RneVsMo3azdEJ8UYTmz86dz0Cx5ciIsw
|
140 | to-salty-id: oU3lbcpdHo81Eo8SifwoHg5CEEZ5q-Rb0_zMWpJU-GWlr9lIjILqv5RneVsMo3azdEJ8UYTmz86dz0Cx5ciIsw
|
141 | signature: vtQQktMrFEszVSeVMgqN22EPOCMjZQZvA2TZkujcE7BtXAv9Lf7k1P4HE1D/c/XoIPvoQ8LiHJEgumWlgGuNDg==
|
142 | ```
|
143 |
|
144 | ### Signature
|
145 |
|
146 | Always contains the signer's public keys, a sha256 HMAC to authenticate the file, keyed with a 32-byte random nonce, and a signature.
|
147 |
|
148 | ```
|
149 | from-salty-id: base64(encryptPk (32) + verifyPk (32))
|
150 | hash: base64( sha256_hmac( nonce ) of file )
|
151 | nonce: base64( randomNonce (32) )
|
152 | signature: base64( detached sig of previous headers )
|
153 | ```
|
154 |
|
155 | Example:
|
156 |
|
157 | ```
|
158 | from-salty-id: jbMGsmaXG7bJLZjhnn/i+9GyQtEVBBTL8JwdpBgKC0y6wvvEbesSYp4vOkjOEt5IZtt0pdrXI2ARZKkAIHUnhg==
|
159 | nonce: rKtBFyFXZbLrmCzUsxVKlqPkYinmOWqvJSLN3Oyhejg=
|
160 | hash: gXkCnKr04zD8rTzs++17z9LWGoNgWceSo2XQXQJOFSQ=
|
161 | signature: QqXQ8EMqpqrC8OZvNssh5dt45NHiYMuRsPjZAOjIQSvUxrgrX+fVjLVwPmulP7h3l4mqcK64BpnzphRS5UpYDg==
|
162 | ```
|
163 |
|
164 | ## Usage
|
165 |
|
166 | ```
|
167 | Usage: salty [options] [command]
|
168 |
|
169 |
|
170 | Commands:
|
171 |
|
172 | init initialize or update a wallet
|
173 | id|pubkey output your shareable pubkey string
|
174 | import|i <pubkey|url|file> import a pubkey
|
175 | ls|l list imported keys
|
176 | encrypt|e [options] [infile|indir] [outfile] encrypt a file
|
177 | decrypt|d [options] <infile|gist> [outfile] decrypt and verify a file
|
178 | sign|s [options] <infile> [outfile] create a ".salty-sig" signature file
|
179 | verify|v <insig> [infile] verify a ".salty-sig" signature with the original file
|
180 | save [indir] [outfile] save an encrypted backup of your wallet
|
181 | restore [infile] [outdir] restore your wallet from a backup
|
182 |
|
183 | Options:
|
184 |
|
185 | -h, --help output usage information
|
186 | -V, --version output the version number
|
187 | -w, --wallet <dir> wallet location (default: ~/.salty)
|
188 | -F, --force do it anyway
|
189 | ```
|
190 |
|
191 | ### salty encrypt
|
192 |
|
193 | ```
|
194 | Usage: encrypt|e [options] [infile|indir] [outfile]
|
195 |
|
196 | encrypt a file
|
197 |
|
198 | Options:
|
199 |
|
200 | -h, --help output usage information
|
201 | -t, --to <email> email address to encrypt for. (must be imported first. default: self)
|
202 | -n, --nonce <nonce> use a specific nonce (base64-encoded)
|
203 | -m, --message compose a message instead of using [infile] (implies -a)
|
204 | -s, --sign sign the message to reveal/prove our identity
|
205 | -a, --armor output as a PEM to STDOUT
|
206 | -g, --gist upload encrypted result as a gist
|
207 | -F, --force ignore warnings and do it
|
208 | -D, --delete delete the original file after encryption
|
209 | ```
|
210 |
|
211 | ### salty decrypt
|
212 |
|
213 | ```
|
214 | Usage: decrypt|d [options] <infile|gist> [outfile]
|
215 |
|
216 | decrypt and verify a file
|
217 |
|
218 | Options:
|
219 |
|
220 | -h, --help output usage information
|
221 | -s, --sig require a signature
|
222 | -a, --armor expect PEM format, output to STDOUT
|
223 | -g, --gist download the encrypted input from a gist
|
224 | -F, --force ignore warnings and do it
|
225 | -D, --delete delete the salty file after verification
|
226 | ```
|
227 |
|
228 | ## Log
|
229 |
|
230 | ### release v3.1.0
|
231 |
|
232 | - Added anonymous gist support
|
233 | - Added tar/gz support for encrypting directories
|
234 |
|
235 | ### TODO
|
236 |
|
237 | - Custom headers, repeatable -H param
|
238 |
|
239 | - - -
|
240 |
|
241 | ### License: MIT
|
242 |
|
243 | - Copyright (C) 2016 Carlos Rodriguez (http://s8f.org/)
|
244 | - Copyright (C) 2016 Terra Eclipse, Inc. (http://www.terraeclipse.com/)
|
245 |
|
246 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
247 | of this software and associated documentation files (the "Software"), to deal
|
248 | in the Software without restriction, including without limitation the rights
|
249 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
250 | copies of the Software, and to permit persons to whom the Software is furnished
|
251 | to do so, subject to the following conditions:
|
252 |
|
253 | The above copyright notice and this permission notice shall be included in
|
254 | all copies or substantial portions of the Software.
|
255 |
|
256 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
257 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
258 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
259 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
260 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
261 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
262 | SOFTWARE. |
\ | No newline at end of file |