Skip to content

Instantly share code, notes, and snippets.

@ozgun
Last active December 29, 2015 10:39
Show Gist options
  • Select an option

  • Save ozgun/7658375 to your computer and use it in GitHub Desktop.

Select an option

Save ozgun/7658375 to your computer and use it in GitHub Desktop.
Generating One-Time Password using both HOTP and TOTP
# encoding: utf-8
require 'openssl'
require "base64"
# https://github.com/mdp/rotp
require 'rotp'
def truncate_hmac(hmac, padded=true)
digits = 6
offset = hmac[-1].ord & 0xf
code = (hmac[offset].ord & 0x7f) << 24 |
(hmac[offset + 1].ord & 0xff) << 16 |
(hmac[offset + 2].ord & 0xff) << 8 |
(hmac[offset + 3].ord & 0xff)
if padded
(code % 10 ** digits).to_s.rjust(digits, '0')
else
code % 10 ** digits
end
end
def int_to_bytestring(int, padding = 8)
result = []
until int == 0
result << (int & 0xFF).chr
int >>= 8
end
result.reverse.join.rjust(padding, 0.chr)
end
def hotp_plus_totp
key = "JCAYAA4U23D7V2EC"
counter = 0
current_time = 1385472664
time_index = current_time / 30
counter_byte_array = int_to_bytestring(counter)
time_byte_array = int_to_bytestring(time_index)
base32_decoded_key = ROTP::Base32.decode(key)
hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), base32_decoded_key, counter_byte_array)
hmac2 = OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), hmac, time_byte_array)
return "HOTP+TOTP: #{truncate_hmac(hmac2)} - Time index: #{time_index} - Counter: #{counter}"
end
puts hotp_plus_totp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment