Class Rails::SecretKeyGenerator
In: vendor/rails/railties/lib/rails_generator/secret_key_generator.rb
Parent: Object

Methods

Constants

GENERATORS = [ :secure_random, :win32_api, :urandom, :openssl, :prng ].freeze

Public Class methods

[Source]

    # File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 12
12:     def initialize(identifier)
13:       @identifier = identifier
14:     end

Public Instance methods

Generate a random secret key with the best possible method available on the current platform.

[Source]

    # 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.

[Source]

    # 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.

[Source]

     # 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.

[Source]

    # 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.

[Source]

    # 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.

[Source]

    # 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

[Validate]