Class: SecondFactor::OTP

Inherits:
Object
  • Object
show all
Defined in:
lib/secondfactor/otp.rb

Class Method Summary collapse

Class Method Details

.generate_hmac(seed_based, step) ⇒ Object



10
11
12
13
14
15
16
17
18
19
# 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) ⇒ Object



3
4
5
6
7
8
# 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) ⇒ Object

Roughly adapted from github.com/aeyris/otp



22
23
24
25
26
27
28
29
30
31
# 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