forked from nginx-modules/ngx_http_hmac_secure_link_module
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME
130 lines (97 loc) · 4.14 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Nginx HMAC Secure Link Module
--
Description:
--
The Nginx HMAC secure link module enhances the security and functionality
of the standard secure link module. Secure token is created using secure
HMAC construction with an arbitrary hash algorithm supported by OpenSSL,
e.g., md5, sha1, sha256, sha512. Furthermore, secure token is created as
described in RFC2104, that is,
H(secret_key XOR opad,H(secret_key XOR ipad, message))
instead of a simple
MD5(secret_key,message, expire).
Installation:
--
You'll need to re-compile Nginx from source to include this module.
Modify your compile of Nginx by adding the following directive
(modified to suit your path of course):
./configure --add-module=/absolute/path/to/nginx-hmac-secure-link
make
make install
Usage:
--
Message to be hashed is defined by secure_link_hmac_message, secret_key
is given by secure_link_hmac_secret, and hashing algorithm H is defined
by secure_link_hmac_algorithm. For improved security the timestamp in
ISO 8601 format should be appended to the message to be hashed.
It is possible to create links with limited lifetime. This is defined by
an optional parameter. If the expiration period is zero or it is not specified,
a link has the unlimited lifetime.
Configuration example for server side.
location ^~ /files/ {
# Variable to be passed are secure token, timestamp, expiration period (optional)
secure_link $arg_st,$arg_ts,$arg_e;
# Secret key
secure_link_hmac_secret my_secret_key;
# Message to be verified
secure_link_hmac_message $uri$arg_ts$arg_e;
# Cryptographic hash function to be used
secure_link_hmac_algorithm sha256;
# If the hash is incorrect then $secure_link is a null string.
# If the hash is correct but the link has already expired then $secure_link is zero.
# If the hash is correct and the link has not expired then $secure_link is one.
# In production environment, we should not reveal to potential attacker
# why hmac authentication has failed
if ($secure_link != "1") {
return 404;
}
rewrite ^/files/(.*)$ /files/$1 break;
}
Application side should use a standard hash_hmac function to generate hash, which
then needs to be base64url encoded. Example in Perl below.
# Variable $data contains secure token, timestamp in ISO 8601 format, and expiration
# period in seconds
perl_set $secure_token '
sub {
use Digest::SHA qw(hmac_sha256_base64);
use POSIX qw(strftime);
my $now = time();
my $tz = strftime("%z", localtime($now));
$tz =~ s/(\d{2})(\d{2})/$1:$2/;
my $timestamp = strftime("%Y-%m-%dT%H:%M:%S", localtime($now)) . $tz;
my $expire = 60;
my $key = "my_very_secret_key";
my $r = shift;
my $data = $r->uri;
my $digest = hmac_sha256_base64($data . $timestamp . $expire, $key);
$digest =~ tr(+/)(-_);
$data = "st=" . $digest . "&ts=" . $timestamp . "&e=" . $expire;
return $data;
}
';
A similar function in PHP
$timestamp = date("c");
$expire = 60;
$secret = "my_very_secret_key";
$algo = "sha256";
$stringtosign = "/files/top_secret.pdf" . $timestamp . $expire;
$hashmac = base64_encode(hash_hmac($algo,$stringtosign,$secret,true));
$hashmac = strtr($hashmac,"+/","-_"));
$hashmac = str_replace("=","",$hashmac);
$host = $_SERVER['HTTP_HOST'];
$loc = "https://" . $host . "/files/top_secret.pdf" . "?st=" . $hashmac . "&ts=" . $timestamp . "&e=" . $expire;
It is also possible to use this module with a Nginx acting as proxy server.
The string to be signed is defined in secure_link_hmac_message, the secure_link_token
variable contains then a secure token to be passed to backend server.
location ^~ /backend_location/ {
set $expire 60;
secure_link_hmac_message $uri$time_iso8601$expire;
secure_link_hmac_secret "my_very_secret_key";
secure_link_hmac_algorithm sha256;
proxy_pass http://backend_server$uri?st=$secure_link_token&ts=$time_iso8601&e=$expire;
}
Contributing:
--
Git source repositories:
http://github.com/timo2/nginx-hmac-secure-link/tree/master
Please feel free to fork the project at GitHub and submit pull requests or patches.