| Class | Rails::SecretKeyGenerator |
| In: |
vendor/rails/railties/lib/rails_generator/secret_key_generator.rb
|
| Parent: | Object |
| GENERATORS | = | [ :secure_random, :win32_api, :urandom, :openssl, :prng ].freeze |
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 12
12: def initialize(identifier)
13: @identifier = identifier
14: end
Generate a random secret key with the best possible method available on the current platform.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 18
18: def generate_secret
19: generator = GENERATORS.find do |g|
20: self.class.send("supports_#{g}?")
21: end
22: send("generate_secret_with_#{generator}")
23: end
Generate a random secret key with OpenSSL. If OpenSSL is not already loaded, then this method will attempt to load it. LoadError will be raised if that fails.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 68
68: def generate_secret_with_openssl
69: require 'openssl'
70: if !File.exist?("/dev/urandom")
71: # OpenSSL transparently seeds the random number generator with
72: # data from /dev/urandom. On platforms where that is not
73: # available, such as Windows, we have to provide OpenSSL with
74: # our own seed. Unfortunately there's no way to provide a
75: # secure seed without OS support, so we'll have to do with
76: # rand() and Time.now.usec().
77: OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s)
78: end
79: data = OpenSSL::BN.rand(2048, -1, false).to_s
80: return OpenSSL::Digest::SHA512.new(data).hexdigest
81: end
Generate a random secret key with Ruby‘s pseudo random number generator, as well as some environment information.
This is the least cryptographically secure way to generate a secret key, and should be avoided whenever possible.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 94
94: def generate_secret_with_prng
95: require 'digest/sha2'
96: sha = Digest::SHA2.new(512)
97: now = Time.now
98: sha << now.to_s
99: sha << String(now.usec)
100: sha << String(rand(0))
101: sha << String($$)
102: sha << @identifier
103: return sha.hexdigest
104: end
Generate a random secret key with Ruby 1.9‘s SecureRandom module. Raises LoadError if the current Ruby version does not support SecureRandom.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 60
60: def generate_secret_with_secure_random
61: require 'securerandom'
62: return SecureRandom.hex(64)
63: end
Generate a random secret key with /dev/urandom. Raises SystemCallError on failure.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 85
85: def generate_secret_with_urandom
86: return File.read("/dev/urandom", 64).unpack("H*")[0]
87: end
Generate a random secret key by using the Win32 API. Raises LoadError if the current platform cannot make use of the Win32 API. Raises SystemCallError if some other error occured.
# File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 28
28: def generate_secret_with_win32_api
29: # Following code is based on David Garamond's GUID library for Ruby.
30: require 'Win32API'
31:
32: crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext",
33: 'PPPII', 'L')
34: crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom",
35: 'LIP', 'L')
36: crypt_release_context = Win32API.new("advapi32", "CryptReleaseContext",
37: 'LI', 'L')
38: prov_rsa_full = 1
39: crypt_verifycontext = 0xF0000000
40:
41: hProvStr = " " * 4
42: if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full,
43: crypt_verifycontext) == 0
44: raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
45: end
46: hProv, = hProvStr.unpack('L')
47: bytes = " " * 64
48: if crypt_gen_random.call(hProv, bytes.size, bytes) == 0
49: raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
50: end
51: if crypt_release_context.call(hProv, 0) == 0
52: raise SystemCallError, "CryptReleaseContext failed: #{lastWin32ErrorMessage}"
53: end
54: bytes.unpack("H*")[0]
55: end