class SecondFactor::OTP
Public Class Methods
generate_hmac(seed_based, step)
click to toggle source
# File lib/secondfactor/otp.rb, line 10 def self.generate_hmac(seed_based, step) seed_bytes = Base32.decode(seed_based) hmac = OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha1"), seed_bytes, self.intbytes(step)) # https://tools.ietf.org/html/rfc4226#section-5.4 offset = hmac[-1].ord & 0xF truncated = (hmac[offset].ord & 0x7F) << 24 | (hmac[offset + 1].ord & 0xFF) << 16 | (hmac[offset + 2].ord & 0xFF) << 8 | (hmac[offset + 3].ord & 0xFF) return truncated end
generate_seed(length=10)
click to toggle source
# File lib/secondfactor/otp.rb, line 3 def self.generate_seed(length=10) seed_bytes = (0...length).map { rand(255).chr } seed_based = Base32.encode(seed_bytes.join) return seed_based end
intbytes(int)
click to toggle source
Roughly adapted from github.com/aeyris/otp
# File lib/secondfactor/otp.rb, line 22 def self.intbytes(int) result = "" 8.times do result << (int & 0xFF).chr int >>= 8 end return result.reverse.rjust(8, 0.chr) end