module ActiveSupport::SecurityUtils
Public Class Methods
fixed_length_secure_compare(a, b)
click to toggle source
Constant time string comparison, for fixed length strings.
The values compared should be of fixed length, such as strings that have already been processed by HMAC. Raises in case of length mismatch.
# File lib/active_support/security_utils.rb, line 11 def fixed_length_secure_compare(a, b) raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize l = a.unpack "C#{a.bytesize}" res = 0 b.each_byte { |byte| res |= byte ^ l.shift } res == 0 end
secure_compare(a, b)
click to toggle source
Constant time string comparison, for variable length strings.
The values are first processed by SHA256, so that we don't leak length info via timing attacks.
# File lib/active_support/security_utils.rb, line 26 def secure_compare(a, b) fixed_length_secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) && a == b end
Private Instance Methods
fixed_length_secure_compare(a, b)
click to toggle source
Constant time string comparison, for fixed length strings.
The values compared should be of fixed length, such as strings that have already been processed by HMAC. Raises in case of length mismatch.
# File lib/active_support/security_utils.rb, line 11 def fixed_length_secure_compare(a, b) raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize l = a.unpack "C#{a.bytesize}" res = 0 b.each_byte { |byte| res |= byte ^ l.shift } res == 0 end
secure_compare(a, b)
click to toggle source
Constant time string comparison, for variable length strings.
The values are first processed by SHA256, so that we don't leak length info via timing attacks.
# File lib/active_support/security_utils.rb, line 26 def secure_compare(a, b) fixed_length_secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) && a == b end