Class: SecondFactor::OTP
- Inherits:
-
Object
- Object
- SecondFactor::OTP
- Defined in:
- lib/secondfactor/otp.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#intbytes(int) ⇒ Object
Roughly adapted from github.com/aeyris/otp.
Class Method Details
.generate_hmac(seed_based, step) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 |
# 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, intbytes(step)) # https://tools.ietf.org/html/rfc4226#section-5.4 # What's security without a bit of math I don't understand, right? # Lucky that RFC is easy to understand... 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 |
Instance Method Details
#intbytes(int) ⇒ Object
Roughly adapted from github.com/aeyris/otp
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/secondfactor/otp.rb', line 24 def intbytes(int) result = "" 8.times do result << (int & 0xFF).chr int >>= 8 end return result.reverse.rjust(8, 0.chr) end |