Class: SIRP::Client
Constant Summary
Constants included from SIRP
Instance Attribute Summary collapse
-
#A ⇒ Object
readonly
Returns the value of attribute A.
-
#a ⇒ Object
readonly
Returns the value of attribute a.
-
#g ⇒ Object
readonly
Returns the value of attribute g.
-
#H_AMK ⇒ Object
readonly
Returns the value of attribute H_AMK.
-
#hash ⇒ Object
readonly
Returns the value of attribute hash.
-
#k ⇒ Object
readonly
Returns the value of attribute k.
-
#K ⇒ Object
readonly
Returns the value of attribute K.
-
#M ⇒ Object
readonly
Returns the value of attribute M.
-
#N ⇒ Object
readonly
Returns the value of attribute N.
-
#S ⇒ Object
readonly
Returns the value of attribute S.
Instance Method Summary collapse
-
#initialize(group = 2048) ⇒ Client
constructor
Select modulus (N), generator (g), and one-way hash function (SHA1 or SHA256).
-
#process_challenge(username, password, xsalt, xbb) ⇒ String
Phase 2 : Step 1 : Process the salt and B values provided by the server.
-
#start_authentication ⇒ String
Phase 1 : Step 1 : Start the authentication process by generating the client ‘a’ and ‘A’ values.
-
#verify(server_HAMK) ⇒ true, false
Phase 2 : Step 3 : Verify that the server provided H(A,M,K) value matches the client generated version.
Methods included from SIRP
#H, #Ng, #calc_A, #calc_B, #calc_H_AMK, #calc_M, #calc_client_S, #calc_k, #calc_server_S, #calc_u, #calc_v, #calc_x, #hex_to_bytes, #mod_exp, #num_to_hex, #secure_compare, #sha_hex, #sha_str
Constructor Details
#initialize(group = 2048) ⇒ Client
Select modulus (N), generator (g), and one-way hash function (SHA1 or SHA256)
9 10 11 12 13 14 15 |
# File 'lib/sirp/client.rb', line 9 def initialize(group = 2048) raise ArgumentError, 'must be an Integer' unless group.is_a?(Integer) raise ArgumentError, 'must be a known group size' unless [1024, 1536, 2048, 3072, 4096, 6144, 8192].include?(group) @N, @g, @hash = Ng(group) @k = calc_k(@N, @g, hash) end |
Instance Attribute Details
#A ⇒ Object (readonly)
Returns the value of attribute A.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def A @A end |
#a ⇒ Object (readonly)
Returns the value of attribute a.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def a @a end |
#g ⇒ Object (readonly)
Returns the value of attribute g.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def g @g end |
#H_AMK ⇒ Object (readonly)
Returns the value of attribute H_AMK.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def H_AMK @H_AMK end |
#hash ⇒ Object (readonly)
Returns the value of attribute hash.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def hash @hash end |
#k ⇒ Object (readonly)
Returns the value of attribute k.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def k @k end |
#K ⇒ Object (readonly)
Returns the value of attribute K.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def K @K end |
#M ⇒ Object (readonly)
Returns the value of attribute M.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def M @M end |
#N ⇒ Object (readonly)
Returns the value of attribute N.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def N @N end |
#S ⇒ Object (readonly)
Returns the value of attribute S.
4 5 6 |
# File 'lib/sirp/client.rb', line 4 def S @S end |
Instance Method Details
#process_challenge(username, password, xsalt, xbb) ⇒ String
Phase 2 : Step 1 : Process the salt and B values provided by the server.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/sirp/client.rb', line 39 def process_challenge(username, password, xsalt, xbb) raise ArgumentError, 'username must be a string' unless username.is_a?(String) && !username.empty? raise ArgumentError, 'password must be a string' unless password.is_a?(String) && !password.empty? raise ArgumentError, 'xsalt must be a string' unless xsalt.is_a?(String) raise ArgumentError, 'xsalt must be a hex string' unless xsalt =~ /^[a-fA-F0-9]+$/ raise ArgumentError, 'xbb must be a string' unless xbb.is_a?(String) raise ArgumentError, 'xbb must be a hex string' unless xbb =~ /^[a-fA-F0-9]+$/ # Convert the 'B' hex value to an Integer bb = xbb.to_i(16) # SRP-6a safety check return false if (bb % @N).zero? x = calc_x(username, password, xsalt, hash) u = calc_u(@A, xbb, @N, hash) # SRP-6a safety check return false if u.zero? # Calculate session key 'S' and secret key 'K' @S = num_to_hex(calc_client_S(bb, @a, @k, x, u, @N, @g)) @K = sha_hex(@S, hash) # Calculate the 'M' matcher @M = calc_M(@A, xbb, @K, hash) # Calculate the H(A,M,K) verifier @H_AMK = num_to_hex(calc_H_AMK(@A, @M, @K, hash)) # Return the 'M' matcher to be sent to the server @M end |
#start_authentication ⇒ String
Phase 1 : Step 1 : Start the authentication process by generating the client ‘a’ and ‘A’ values. Public ‘A’ should later be sent along with the username, to the server verifier to continue the auth process. The internal secret ‘a’ value should remain private.
23 24 25 26 |
# File 'lib/sirp/client.rb', line 23 def start_authentication @a ||= SecureRandom.hex(32).hex @A = num_to_hex(calc_A(@a, @N, @g)) end |
#verify(server_HAMK) ⇒ true, false
Phase 2 : Step 3 : Verify that the server provided H(A,M,K) value matches the client generated version. This is the last step of mutual authentication and confirms that the client and server have completed the auth process. The comparison of local and server H_AMK values is done using a secure constant-time comparison method so as not to leak information.
86 87 88 89 90 91 92 93 94 |
# File 'lib/sirp/client.rb', line 86 def verify(server_HAMK) return false unless @H_AMK && server_HAMK return false unless server_HAMK.is_a?(String) return false unless server_HAMK =~ /^[a-fA-F0-9]+$/ # Hash the comparison params to ensure that both strings # being compared are equal length 32 Byte strings. secure_compare(Digest::SHA256.hexdigest(@H_AMK), Digest::SHA256.hexdigest(server_HAMK)) end |