module ActiveSupport::SecurityUtils
def fixed_length_secure_compare(a, b)
The values compared should be of fixed length, such as strings
Constant time string comparison, for fixed length strings.
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
def secure_compare(a, b)
The values are first processed by SHA256, so that we don't leak length info
Constant time string comparison, for variable length strings.
def secure_compare(a, b) fixed_length_secure_compare(::Digest::SHA256.digest(a), ::Digest::SHA256.digest(b)) && a == b end