1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
require File.expand_path(File.dirname(__FILE__) + '/util')
module SRP
class Client
include Util
attr_reader :salt, :verifier
def initialize(username, password, salt = nil)
@username = username
@password = password
@salt = salt || bigrand(4).hex
@multiplier = multiplier # let's cache it
calculate_verifier
end
def authenticate(server)
a = bigrand(32).hex
aa = modpow(GENERATOR, a) # A = g^a (mod N)
bb = server.handshake(@username, aa)
u = calculate_u(aa, bb)
client_s = calculate_client_s(private_key, a, bb, u)
server.validate(calculate_m(aa, bb, client_s))
end
protected
def calculate_verifier
@verifier ||= modpow(GENERATOR, private_key)
end
def private_key
@private_key ||= calculate_private_key
end
def calculate_private_key
shex = '%x' % [@salt]
inner = sha256_str([@username, @password].join(':'))
sha256_hex(shex, inner).hex
end
def calculate_client_s(x, a, bb, u)
base = bb
base += BIG_PRIME_N * @multiplier
base -= modpow(GENERATOR, x) * @multiplier
base = base % BIG_PRIME_N
modpow(base, x * u + a)
end
end
end
|