Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
1fac9c74
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
1fac9c74
编写于
5月 13, 2011
作者:
A
Aaron Patterson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
securerandom ships with 1.8.7+, so just use it
上级
cbe6e09f
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
3 addition
and
202 deletion
+3
-202
activesupport/lib/active_support/secure_random.rb
activesupport/lib/active_support/secure_random.rb
+3
-202
未找到文件。
activesupport/lib/active_support/secure_random.rb
浏览文件 @
1fac9c74
begin
require
'securerandom'
rescue
LoadError
end
require
'securerandom'
module
ActiveSupport
if
defined?
(
::
SecureRandom
)
# Use Ruby's SecureRandom library if available.
# Use Ruby's SecureRandom library.
SecureRandom
=
::
SecureRandom
# :nodoc:
else
# = Secure random number generator interface.
#
# This library is an interface for secure random number generator which is
# suitable for generating session key in HTTP cookies, etc.
#
# It supports following secure random number generators.
#
# * openssl
# * /dev/urandom
# * Win32
#
# *Note*: This module is based on the SecureRandom library from Ruby 1.9,
# revision 18786, August 23 2008. It's 100% interface-compatible with Ruby 1.9's
# SecureRandom library.
#
# == Example
#
# # random hexadecimal string.
# p SecureRandom.hex(10) # => "52750b30ffbc7de3b362"
# p SecureRandom.hex(10) # => "92b15d6c8dc4beb5f559"
# p SecureRandom.hex(11) # => "6aca1b5c58e4863e6b81b8"
# p SecureRandom.hex(12) # => "94b2fff3e7fd9b9c391a2306"
# p SecureRandom.hex(13) # => "39b290146bea6ce975c37cfc23"
# ...
#
# # random base64 string.
# p SecureRandom.base64(10) # => "EcmTPZwWRAozdA=="
# p SecureRandom.base64(10) # => "9b0nsevdwNuM/w=="
# p SecureRandom.base64(10) # => "KO1nIU+p9DKxGg=="
# p SecureRandom.base64(11) # => "l7XEiFja+8EKEtY="
# p SecureRandom.base64(12) # => "7kJSM/MzBJI+75j8"
# p SecureRandom.base64(13) # => "vKLJ0tXBHqQOuIcSIg=="
# ...
#
# # random binary string.
# p SecureRandom.random_bytes(10) # => "\016\t{\370g\310pbr\301"
# p SecureRandom.random_bytes(10) # => "\323U\030TO\234\357\020\a\337"
# ...
#
module
SecureRandom
# Generates a random binary string.
#
# The argument n specifies the length of the result string.
#
# If n is not specified, 16 is assumed.
# It may be larger in future.
#
# If secure random number generator is not available,
# NotImplementedError is raised.
#
def
self
.
random_bytes
(
n
=
nil
)
n
||=
16
unless
defined?
OpenSSL
begin
require
'openssl'
rescue
LoadError
end
end
if
defined?
OpenSSL
::
Random
return
OpenSSL
::
Random
.
random_bytes
(
n
)
end
if
!
defined?
(
@has_urandom
)
||
@has_urandom
flags
=
File
::
RDONLY
flags
|=
File
::
NONBLOCK
if
defined?
File
::
NONBLOCK
flags
|=
File
::
NOCTTY
if
defined?
File
::
NOCTTY
flags
|=
File
::
NOFOLLOW
if
defined?
File
::
NOFOLLOW
begin
File
.
open
(
"/dev/urandom"
,
flags
)
{
|
f
|
unless
f
.
stat
.
chardev?
raise
Errno
::
ENOENT
end
@has_urandom
=
true
ret
=
f
.
readpartial
(
n
)
if
ret
.
length
!=
n
raise
NotImplementedError
,
"Unexpected partial read from random device"
end
return
ret
}
rescue
Errno
::
ENOENT
@has_urandom
=
false
end
end
unless
defined?
(
@has_win32
)
begin
require
'Win32API'
crypt_acquire_context
=
Win32API
.
new
(
"advapi32"
,
"CryptAcquireContext"
,
'PPPII'
,
'L'
)
@crypt_gen_random
=
Win32API
.
new
(
"advapi32"
,
"CryptGenRandom"
,
'LIP'
,
'L'
)
hProvStr
=
" "
*
4
prov_rsa_full
=
1
crypt_verifycontext
=
0xF0000000
if
crypt_acquire_context
.
call
(
hProvStr
,
nil
,
nil
,
prov_rsa_full
,
crypt_verifycontext
)
==
0
raise
SystemCallError
,
"CryptAcquireContext failed:
#{
lastWin32ErrorMessage
}
"
end
@hProv
,
=
hProvStr
.
unpack
(
'L'
)
@has_win32
=
true
rescue
LoadError
@has_win32
=
false
end
end
if
@has_win32
bytes
=
" "
*
n
if
@crypt_gen_random
.
call
(
@hProv
,
bytes
.
size
,
bytes
)
==
0
raise
SystemCallError
,
"CryptGenRandom failed:
#{
lastWin32ErrorMessage
}
"
end
return
bytes
end
raise
NotImplementedError
,
"No random device"
end
# Generates a random hex string.
#
# The argument n specifies the length of the random length.
# The length of the result string is twice of n.
#
# If n is not specified, 16 is assumed.
# It may be larger in future.
#
# If secure random number generator is not available,
# NotImplementedError is raised.
#
def
self
.
hex
(
n
=
nil
)
random_bytes
(
n
).
unpack
(
"H*"
)[
0
]
end
# Generates a random base64 string.
#
# The argument n specifies the length of the random length.
# The length of the result string is about 4/3 of n.
#
# If n is not specified, 16 is assumed.
# It may be larger in future.
#
# If secure random number generator is not available,
# NotImplementedError is raised.
#
def
self
.
base64
(
n
=
nil
)
[
random_bytes
(
n
)].
pack
(
"m*"
).
delete
(
"
\n
"
)
end
# Generates a random number.
#
# If an positive integer is given as n,
# SecureRandom.random_number returns an integer:
# 0 <= SecureRandom.random_number(n) < n.
#
# If 0 is given or an argument is not given,
# SecureRandom.random_number returns an float:
# 0.0 <= SecureRandom.random_number() < 1.0.
#
def
self
.
random_number
(
n
=
0
)
if
0
<
n
hex
=
n
.
to_s
(
16
)
hex
=
'0'
+
hex
if
(
hex
.
length
&
1
)
==
1
bin
=
[
hex
].
pack
(
"H*"
)
mask
=
bin
[
0
]
mask
|=
mask
>>
1
mask
|=
mask
>>
2
mask
|=
mask
>>
4
begin
rnd
=
SecureRandom
.
random_bytes
(
bin
.
length
)
rnd
[
0
]
=
rnd
[
0
]
&
mask
end
until
rnd
<
bin
rnd
.
unpack
(
"H*"
)[
0
].
hex
else
# assumption: Float::MANT_DIG <= 64
i64
=
SecureRandom
.
random_bytes
(
8
).
unpack
(
"Q"
)[
0
]
Math
.
ldexp
(
i64
>>
(
64
-
Float
::
MANT_DIG
),
-
Float
::
MANT_DIG
)
end
end
# Following code is based on David Garamond's GUID library for Ruby.
def
self
.
lastWin32ErrorMessage
# :nodoc:
get_last_error
=
Win32API
.
new
(
"kernel32"
,
"GetLastError"
,
''
,
'L'
)
format_message
=
Win32API
.
new
(
"kernel32"
,
"FormatMessageA"
,
'LPLLPLPPPPPPPP'
,
'L'
)
format_message_ignore_inserts
=
0x00000200
format_message_from_system
=
0x00001000
code
=
get_last_error
.
call
msg
=
"
\0
"
*
1024
len
=
format_message
.
call
(
format_message_ignore_inserts
+
format_message_from_system
,
0
,
code
,
0
,
msg
,
1024
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
)
msg
[
0
,
len
].
tr
(
"
\r
"
,
''
).
chomp
end
end
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录