rotp 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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