GithubHelp home page GithubHelp logo

Comments (4)

mdp avatar mdp commented on July 30, 2024 1

Yeah, so you've selected 3 digits as the OTP, and it's possible that the next OTP is the same as the previous OTP. The OTP's are generated by HMAC, but then boil that down into x number of digits, so it's entirely possible (and likely with 3 digits) that you get a 'collision' where the next (or previous) OTP is the same.

On each iteration, you choose the same time (for the most part but depends on when you run it), but Foobar is creating a new random key for each run. At some point, out of 1000 runs, some random key at say "2021-03-18 18:31:00" gives the same OTP at "2021-03-18 18:32:00" and it's failing.

If you increase it to 6 digits it will fail less often, but it will still fail from time to time.

Let me know if that answers your question.

from rotp.

Linuus avatar Linuus commented on July 30, 2024

Ah ok, I see. Thanks!

from rotp.

benoittgt avatar benoittgt commented on July 30, 2024

@mdp Thanks for the detailed answer. The same issue happens when you drift_behind is very long?

For example

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rotp"
  gem 'activesupport'
end

class Otpable

  DRIFT = 864_000 # 10 days

  attr_accessor(:totp, :proof)

  def initialize
    @totp = ROTP::TOTP.new(ROTP::Base32.random, issuer: 'Club service')
  end

  def generate_otp
    @proof = totp.now
  end

  def verify_otp(drift_behind: DRIFT)
    totp.verify(proof, drift_behind: drift_behind)
  end
end

require 'active_support/testing/time_helpers'

include ActiveSupport::Testing::TimeHelpers

100000000.times do |i|
  optable = Otpable.new

  optable.generate_otp

  print "."
  raise "SHOULD NOT BE NIL" if optable.verify_otp.nil?
  travel_to(Time.now + (Otpable::DRIFT * 2)) do
    raise "SHOULD BE NIL" unless optable.verify_otp.nil?
  end

rescue => e
  puts
  puts "Failed at #{i} times"
  puts
  raise e
end

It is not very effective, but it fails the 63 times.

from rotp.

mdp avatar mdp commented on July 30, 2024

Right, so behind the scenes it's asking if you have a valid OTP and including every OTP generated for the past 10 days (28_800 OTPs or 864_000/30 intervals, which is also why this test is so slow, it's generating and comparing 28k OTPs). Then you're looking at the odds of a collision between one of those 28k OTP's and your current OTP. Your current OTP is 6 digits, so essentially 1_000_000 variations and the odds of a collision is 28_800/1_000_000(2.88%).

Anytime you use drift_behind or drift_ahead you're saying "Included every OTP in the drift time range and consider it valid". Typically you're drift behind would be something like 30 seconds, so you're now comparing the submitted OTP to two valid OTP's, which should be fine for most security situation (1/500_000 odds vs 1/1_000_000). With 10 days drift in either direction you've essentially made it much more likely that any random OTP will be considered valid.

from rotp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.