Comments (4)
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.
Ah ok, I see. Thanks!
from rotp.
@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.
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)
- TOTP wrong code HOT 2
- Warning after upgrading to Ruby version 2.7.2 HOT 2
- Would you be willing to add a 6.2 tag? HOT 1
- Undefined method verify_with_drift HOT 2
- TOTP deemed invalid within the `interval` HOT 2
- CVE Alert due to bundling jQuery 1.4.2 HOT 3
- Cannot verify OTP in a separate request HOT 2
- Ruby 2.3 needs older Bundler to work
- rotp and mathn HOT 1
- Expired code if internal was set more than 1 minute HOT 1
- No option to set drift/at in HOTP HOT 1
- Feature Request SHA256 based TOTP HOT 4
- wrong code - oauthtool vs mdp/rotp HOT 3
- Wrong number of arguments error HOT 1
- Missing tag for rotp v5.0.0 HOT 1
- Please explain what happened to #random_base32 HOT 1
- How to save a secret code to a user HOT 1
- spaces double-encode in issuer parameter field
- Proposal: create backup code function HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rotp.