urlcrypt 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -19
- data/Rakefile +2 -1
- data/lib/URLcrypt.rb +6 -4
- data/test/URLcrypt_test.rb +15 -1
- metadata +4 -4
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# URLcrypt
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/
|
3
|
+
[![Build Status](https://travis-ci.org/cheerful/URLcrypt.png?branch=master)](https://travis-ci.org/cheerful/URLcrypt)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/cheerful/URLcrypt/badge.png?branch=master)](https://coveralls.io/r/cheerful/URLcrypt)
|
4
5
|
|
5
6
|
Ever wanted to securely transmit (not too long) pieces of arbitrary binary data
|
6
7
|
in a URL? **URLcrypt** makes it easy!
|
@@ -8,42 +9,45 @@ in a URL? **URLcrypt** makes it easy!
|
|
8
9
|
This gem is based on the [base32](https://github.com/stesla/base32) gem from Samuel Tesla.
|
9
10
|
|
10
11
|
URLcrypt uses **256-bit AES symmetric encryption**
|
11
|
-
to securely encrypt data, and encodes and decodes
|
12
|
+
to securely encrypt data, and encodes and decodes
|
12
13
|
**Base 32 strings that can be used directly in URLs**.
|
13
14
|
|
14
|
-
This can be used to securely store user ids, download expiration dates and
|
15
|
-
other arbitrary data like that when you access a web application from a place
|
15
|
+
This can be used to securely store user ids, download expiration dates and
|
16
|
+
other arbitrary data like that when you access a web application from a place
|
16
17
|
that doesn't have other authentication or persistence mechanisms (like cookies):
|
17
|
-
|
18
|
+
|
18
19
|
* Loading a generated image from your web app in an email
|
19
20
|
* Links that come with an expiration date (à la S3)
|
20
21
|
* Mini-apps that don't persist data on the server
|
21
22
|
|
22
23
|
Works with Ruby 1.8, 1.9 and 2.0.
|
23
24
|
|
24
|
-
**Important**: As a general guideline, URL lengths shouldn't exceed about 2000
|
25
|
+
**Important**: As a general guideline, URL lengths shouldn't exceed about 2000
|
25
26
|
characters in length, as URLs longer than that will not work in some browsers
|
26
27
|
and with some (proxy) servers. This limits the amount of data you can store
|
27
28
|
with URLcrypt.
|
28
29
|
|
29
30
|
**WORD OF WARNING: THERE IS NO GUARANTEE WHATSOEVER THAT THIS GEM IS ACTUALLY SECURE AND WORKS. USE AT YOUR OWN RISK.**
|
30
31
|
|
32
|
+
URLcrypt is an extraction from [Freckle Time Tracking](http://letsfreckle.com/),
|
33
|
+
where it is used to generate URLs for dynamically generated images in emails.
|
34
|
+
|
31
35
|
Patches are welcome; please include tests!
|
32
36
|
|
33
37
|
## Installation
|
34
38
|
|
35
|
-
Add
|
39
|
+
Add `urlcrypt` to your Gemfile.
|
36
40
|
|
37
|
-
##
|
41
|
+
## Example
|
38
42
|
|
39
43
|
```ruby
|
40
44
|
# encrypt and encode with 256-bit AES
|
41
45
|
# one-time setup, set this to a securely random key with at least 256 bits, see below
|
42
|
-
URLcrypt
|
46
|
+
URLcrypt.key = '...'
|
43
47
|
|
44
48
|
# now encrypt and decrypt!
|
45
|
-
URLcrypt
|
46
|
-
URLcrypt
|
49
|
+
URLcrypt.encrypt('chunky bacon!') # => "sgmt40kbmnh1663nvwknxk5l0mZ6Av2ndhgw80rkypnp17xmmg5hy"
|
50
|
+
URLcrypt.decrypt('sgmt40kbmnh1663nvwknxk5l0mZ6Av2ndhgw80rkypnp17xmmg5hy')
|
47
51
|
# => "chunky bacon!"
|
48
52
|
|
49
53
|
# encoding without encryption (don't use for anything sensitive!), doesn't need key set
|
@@ -55,14 +59,14 @@ URLcrypt.decode('mnAhk6tlp2qg2yldn8xcc') # => "chunky bacon!"
|
|
55
59
|
|
56
60
|
The easiest way to generate a secure key is to use `rake secret` in a Rails app:
|
57
61
|
|
58
|
-
```
|
59
|
-
|
62
|
+
```sh
|
63
|
+
$ rake secret
|
60
64
|
ba7f56f8f9873b1653d7f032cc474938fd749ee8fbbf731a7c41d698826aca3cebfffa832be7e6bc16eaddc3826602f35d3fd6b185f261ee8b0f01d33adfbe64
|
61
65
|
```
|
62
66
|
|
63
67
|
To use the key with URLcrypt, you'll need to convert that from a hex string into a real byte array:
|
64
68
|
|
65
|
-
```
|
69
|
+
```ruby
|
66
70
|
URLcrypt::key = ['longhexkeygoeshere'].pack('H*')
|
67
71
|
```
|
68
72
|
|
@@ -71,8 +75,8 @@ URLcrypt::key = ['longhexkeygoeshere'].pack('H*')
|
|
71
75
|
If you want to run the automated tests for URLcrypt, issue this command from the
|
72
76
|
distribution directory.
|
73
77
|
|
74
|
-
```
|
75
|
-
|
78
|
+
```sh
|
79
|
+
$ rake test:all
|
76
80
|
```
|
77
81
|
|
78
82
|
## Why not Base 64, or an other radix/base library?
|
@@ -81,13 +85,13 @@ URLcrypt uses a modified Base 32 algorithm that doesn't use padding characters,
|
|
81
85
|
and doesn't use vowels to avoid bad words in the generated string.
|
82
86
|
|
83
87
|
The main reason why Base 32 is useful is that Ruby's built-in Base 64 support
|
84
|
-
is, IMO, looking ugly in URLs and requires several characters that need to be
|
88
|
+
is, IMO, looking ugly in URLs and requires several characters that need to be
|
85
89
|
URL-escaped.
|
86
90
|
|
87
|
-
Unfortunately, some other gems out there that in theory could handle this
|
91
|
+
Unfortunately, some other gems out there that in theory could handle this
|
88
92
|
(like the radix gem) fail with strings that start with a "\0" byte.
|
89
93
|
|
90
94
|
|
91
95
|
## References
|
92
96
|
|
93
|
-
* Base 32: RFC 3548: http://www.faqs.org/rfcs/rfc3548.html
|
97
|
+
* Base 32: RFC 3548: http://www.faqs.org/rfcs/rfc3548.html
|
data/Rakefile
CHANGED
@@ -24,6 +24,7 @@ require 'rake/clean'
|
|
24
24
|
require 'rake/testtask'
|
25
25
|
require 'rubygems'
|
26
26
|
require 'rubygems/package_task'
|
27
|
+
require 'bundler'
|
27
28
|
|
28
29
|
task :default => ['test:all']
|
29
30
|
|
@@ -37,7 +38,7 @@ gemspec = Gem::Specification.new do |s|
|
|
37
38
|
s.require_paths << 'lib'
|
38
39
|
s.requirements << 'none'
|
39
40
|
s.summary = "Securely encode and decode short pieces of arbitrary binary data in URLs."
|
40
|
-
s.version = "0.1.
|
41
|
+
s.version = "0.1.1"
|
41
42
|
end
|
42
43
|
|
43
44
|
Gem::PackageTask.new(gemspec) do |pkg|
|
data/lib/URLcrypt.rb
CHANGED
@@ -54,10 +54,11 @@ module URLcrypt
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.decrypt(data)
|
57
|
-
|
57
|
+
iv, encrypted = data.split('Z').map{|part| decode(part)}
|
58
|
+
fail DecryptError, "not a valid string to decrypt" unless iv && encrypted
|
58
59
|
decrypter = cipher(:decrypt)
|
59
|
-
decrypter.iv =
|
60
|
-
decrypter.update(
|
60
|
+
decrypter.iv = iv
|
61
|
+
decrypter.update(encrypted) + decrypter.final
|
61
62
|
end
|
62
63
|
|
63
64
|
def self.encrypt(data)
|
@@ -75,4 +76,5 @@ module URLcrypt
|
|
75
76
|
cipher
|
76
77
|
end
|
77
78
|
|
78
|
-
end
|
79
|
+
class DecryptError < ::ArgumentError; end
|
80
|
+
end
|
data/test/URLcrypt_test.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require(:default, :test)
|
4
|
+
|
5
|
+
require 'coveralls'
|
6
|
+
Coveralls.wear!
|
7
|
+
|
2
8
|
require 'test/unit'
|
3
|
-
require 'URLcrypt'
|
4
9
|
|
5
10
|
class TestURLcrypt < Test::Unit::TestCase
|
11
|
+
|
12
|
+
require 'URLcrypt'
|
13
|
+
|
6
14
|
def assert_bytes_equal(string1, string2)
|
7
15
|
bytes1 = string1.bytes.to_a.join(':')
|
8
16
|
bytes2 = string2.bytes.to_a.join(':')
|
@@ -56,4 +64,10 @@ class TestURLcrypt < Test::Unit::TestCase
|
|
56
64
|
assert_equal(URLcrypt::decrypt(encrypted), original)
|
57
65
|
end
|
58
66
|
|
67
|
+
def test_decrypt_error
|
68
|
+
error = assert_raises(URLcrypt::DecryptError) do
|
69
|
+
::URLcrypt::decrypt("just some plaintext")
|
70
|
+
end
|
71
|
+
assert_equal error.message, "not a valid string to decrypt"
|
72
|
+
end
|
59
73
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urlcrypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Thomas Fuchs
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2015-03-18 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description:
|