|
1 |
| -local resty_random = require "resty.random" |
2 |
| - |
3 |
| -local encode_base64 = ngx.encode_base64 |
4 |
| -local gsub = ngx.re.gsub |
5 |
| -local random_bytes = resty_random.bytes |
6 |
| - |
7 | 1 | return function(length)
|
8 |
| - local token = "" |
9 |
| - -- Loop until we've generated a valid token. The basic process: |
10 |
| - -- |
11 |
| - -- 1. Generate secure random bytes. |
12 |
| - -- 2. Convert random bytes to base64. |
13 |
| - -- 3. Strip out special characters from base64 result, so we're left with |
14 |
| - -- just alphanumerics. |
15 |
| - -- |
16 |
| - -- It should be extraordinarily rare that this needs to loop, but since we |
17 |
| - -- strip out some of the special characters from the resulting base64 string, |
18 |
| - -- this loops in case we strip more than expected. |
19 |
| - while string.len(token) < length do |
20 |
| - -- Attempt to generate cryptographically secure random bytes. We |
21 |
| - -- purposefully generate more bytes than we need, since we'll be stripping |
22 |
| - -- some of the base64 characters out. |
23 |
| - local num_bytes = length + 10 |
24 |
| - local strong_random = random_bytes(num_bytes, true) |
25 |
| - if not strong_random then |
26 |
| - ngx.log(ngx.WARN, "Could not generate cryptographically secure random data. Falling back to non-secure random data.") |
27 |
| - strong_random = random_bytes(num_bytes, false) |
28 |
| - end |
29 |
| - |
30 |
| - -- Encode with base64. |
31 |
| - token = token .. encode_base64(strong_random) |
32 |
| - |
33 |
| - -- Strip +, /, and = out of the base64 result, since we just want a-z, A-Z, |
34 |
| - -- and 0-9 in our tokens. |
35 |
| - token = gsub(token, "[+/=]", "", "jo") |
36 |
| - |
37 |
| - -- Take just the number of characters requested. |
38 |
| - token = string.sub(token, 1, length) |
39 |
| - end |
40 |
| - |
41 |
| - return token |
| 2 | + return ndk.set_var.set_secure_random_alphanum(length) |
42 | 3 | end
|
0 commit comments