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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
require File.expand_path(File.dirname(__FILE__) + '/util')
module SRP
class Session
include Util
attr_accessor :user, :aa, :bb
def initialize(user, aa=nil)
@user = user
aa ? initialize_server(aa) : initialize_client
end
# client -> server: I, A = g^a
def handshake(server)
@bb = server.handshake(user.username, aa)
@u = calculate_u
end
# client -> server: M = H(H(N) xor H(g), H(I), s, A, B, K)
def validate(server)
server.validate(calculate_m(client_secret))
end
def authenticate!(m)
authenticate(m) || raise(SRP::WrongPassword)
end
def authenticate(m)
if(m == calculate_m(server_secret))
return calculate_m2
end
end
protected
# only seed b for testing purposes.
def initialize_server(aa, b = nil)
@aa = aa
@b = b || bigrand(32).hex
# B = g^b + k v (mod N)
@bb = (modpow(GENERATOR, @b) + multiplier * @user.verifier) % BIG_PRIME_N
@u = calculate_u
end
def initialize_client
@a = bigrand(32).hex
@aa = modpow(GENERATOR, @a) # A = g^a (mod N)
end
# client: K = H( (B - kg^x) ^ (a + ux) )
def client_secret
base = @bb
# base += BIG_PRIME_N * @multiplier
base -= modpow(GENERATOR, @user.private_key) * multiplier
base = base % BIG_PRIME_N
modpow(base, @user.private_key * @u + @a)
end
# server: K = H( (Av^u) ^ b )
# do not cache this - it's secret and someone might store the
# session in a CookieStore
def server_secret
base = (modpow(@user.verifier, @u) * @aa) % BIG_PRIME_N
modpow(base, @b)
end
# this is outdated - SRP 6a uses
# M = H(H(N) xor H(g), H(I), s, A, B, K)
def calculate_m(secret)
@k = sha256_int(secret).hex
n_xor_g_long = hn_xor_hg.bytes.map{|b| "%02x" % b.ord}.join.hex
username_hash = sha256_str(@user.username).hex
@m = sha256_int(n_xor_g_long, username_hash, @user.salt, @aa, @bb, @k).hex
end
def calculate_m2
sha256_int(@aa, @m, @k).hex
end
def calculate_u
sha256_int(@aa, @bb).hex
end
end
end
|