rotp 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +19 -7
- data/lib/rotp/hotp.rb +7 -0
- data/lib/rotp/totp.rb +6 -0
- data/lib/rotp/version.rb +1 -1
- data/spec/base_spec.rb +15 -0
- metadata +3 -3
data/README.markdown
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# ROTP - The Ruby One Time Password Library
|
2
2
|
|
3
|
+
A ruby library for generating one time passwords according to [ RFC 4226 ](http://tools.ietf.org/html/rfc4226) and the [ HOTP RFC ](http://tools.ietf.org/html/draft-mraihi-totp-timebased-00)
|
4
|
+
|
5
|
+
This is compatible with Google Authenticator apps available for Android and iPhone
|
6
|
+
|
3
7
|
## Dependencies
|
4
8
|
|
5
9
|
* OpenSSL
|
@@ -13,17 +17,24 @@
|
|
13
17
|
|
14
18
|
### Time based OTP's
|
15
19
|
|
16
|
-
totp = ROTP::TOTP.new("
|
20
|
+
totp = ROTP::TOTP.new("base32secret3232")
|
17
21
|
totp.now # => 492039
|
18
|
-
|
22
|
+
|
23
|
+
# OTP verified for current time
|
24
|
+
totp.verify(492039) # => true
|
25
|
+
sleep 30
|
26
|
+
totp.verify(492039) # => false
|
19
27
|
|
20
28
|
### Counter based OTP's
|
21
29
|
|
22
|
-
hotp = ROTP::HOTP.new("
|
23
|
-
hotp.at(0) # =>
|
24
|
-
hotp.at(1) # =>
|
25
|
-
hotp.at(1401) # =>
|
30
|
+
hotp = ROTP::HOTP.new("base32secretkey3232")
|
31
|
+
hotp.at(0) # => 260182
|
32
|
+
hotp.at(1) # => 55283
|
33
|
+
hotp.at(1401) # => 316439
|
26
34
|
|
35
|
+
# OTP verified with a counter
|
36
|
+
totp.verify(316439, 1401) # => true
|
37
|
+
totp.verify(316439, 1402) # => false
|
27
38
|
|
28
39
|
### Generating a Base32 Secret key
|
29
40
|
|
@@ -35,7 +46,8 @@ The library works with the Google Authenticator iPhone and Android app, and also
|
|
35
46
|
includes the ability to generate provisioning URI's for use with the QR Code scanner
|
36
47
|
built into the app.
|
37
48
|
|
38
|
-
|
49
|
+
totp.provisioning_uri # => 'otpauth://totp/alice@google.com?secret=JBSWY3DPEHPK3PXP'
|
50
|
+
hotp.provisioning_uri # => 'otpauth://hotp/alice@google.com?secret=JBSWY3DPEHPK3PXP&counter=0'
|
39
51
|
|
40
52
|
This can then be rendered as a QR Code which can then be scanned and added to the users
|
41
53
|
list of OTP credentials.
|
data/lib/rotp/hotp.rb
CHANGED
@@ -7,6 +7,13 @@ module ROTP
|
|
7
7
|
generate_otp(count)
|
8
8
|
end
|
9
9
|
|
10
|
+
# Verifies the OTP passed in against the current time OTP
|
11
|
+
# @param [String/Integer] otp the OTP to check against
|
12
|
+
# @param [Integer] counter the counter of the OTP
|
13
|
+
def verify(otp, counter)
|
14
|
+
otp == self.at(counter)
|
15
|
+
end
|
16
|
+
|
10
17
|
# Returns the provisioning URI for the OTP
|
11
18
|
# This can then be encoded in a QR Code and used
|
12
19
|
# to provision the Google Authenticator app
|
data/lib/rotp/totp.rb
CHANGED
@@ -26,6 +26,12 @@ module ROTP
|
|
26
26
|
generate_otp(timecode(Time.now))
|
27
27
|
end
|
28
28
|
|
29
|
+
# Verifies the OTP passed in against the current time OTP
|
30
|
+
# @param [String/Integer] otp the OTP to check against
|
31
|
+
def verify(otp, time = Time.now)
|
32
|
+
otp == self.at(time)
|
33
|
+
end
|
34
|
+
|
29
35
|
# Returns the provisioning URI for the OTP
|
30
36
|
# This can then be encoded in a QR Code and used
|
31
37
|
# to provision the Google Authenticator app
|
data/lib/rotp/version.rb
CHANGED
data/spec/base_spec.rb
CHANGED
@@ -26,6 +26,11 @@ describe "HOTP example values from the rfc" do
|
|
26
26
|
hotp.at(8).should ==(399871)
|
27
27
|
hotp.at(9).should ==(520489)
|
28
28
|
end
|
29
|
+
it "should verify an OTP and now allow reuse" do
|
30
|
+
hotp = ROTP::HOTP.new("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ")
|
31
|
+
hotp.verify(520489, 9).should be_true
|
32
|
+
hotp.verify(520489, 10).should be_false
|
33
|
+
end
|
29
34
|
it "should output its provisioning URI" do
|
30
35
|
hotp = ROTP::HOTP.new("wrn3pqx5uqxqvnqr")
|
31
36
|
hotp.provisioning_uri('mark@percival').should == "otpauth://hotp/mark@percival?secret=wrn3pqx5uqxqvnqr&counter=0"
|
@@ -46,6 +51,16 @@ describe "TOTP example values from the rfc" do
|
|
46
51
|
totp.now.should ==(102705)
|
47
52
|
end
|
48
53
|
end
|
54
|
+
it "should validate a time based OTP" do
|
55
|
+
totp = ROTP::TOTP.new("wrn3pqx5uqxqvnqr")
|
56
|
+
Timecop.freeze(Time.at(1297553958)) do
|
57
|
+
totp.verify(102705).should be_true
|
58
|
+
end
|
59
|
+
Timecop.freeze(Time.at(1297553958 + 30)) do
|
60
|
+
totp.verify(102705).should be_false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
49
64
|
|
50
65
|
it "should output its provisioning URI" do
|
51
66
|
totp = ROTP::TOTP.new("wrn3pqx5uqxqvnqr")
|
metadata
CHANGED