srp-rb 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/srp-rb.rb +76 -40
  2. data/lib/srp-rb/version.rb +1 -1
  3. metadata +2 -2
@@ -43,13 +43,20 @@ require "srp-rb/version"
43
43
 
44
44
  module SRP
45
45
  class << self
46
-
47
- def sha1_hex(h)
48
- Digest::SHA1.hexdigest([h].pack('H*'))
46
+
47
+ attr_accessor :hash
48
+
49
+ def sha1_hex(h, hash)
50
+ h = '0' + h if h.size % 2 != 0
51
+ klass = hash == 'sha-256' ?
52
+ Digest::SHA256 : Digest::SHA1
53
+ klass.hexdigest([h].pack('H*'))
49
54
  end
50
55
 
51
- def sha1_str(s)
52
- Digest::SHA1.hexdigest(s)
56
+ def sha1_str(s, hash)
57
+ klass = hash == 'sha-256' ?
58
+ Digest::SHA256 : Digest::SHA1
59
+ klass.hexdigest(s)
53
60
  end
54
61
 
55
62
  def bigrand(bytes)
@@ -70,6 +77,7 @@ module SRP
70
77
  # SHA1 hashing function with padding.
71
78
  # Input is prefixed with 0 to meet N hex width.
72
79
  def H(n, *a)
80
+ hash = a.pop
73
81
  nlen = 2 * ((('%x' % [n]).length * 4 + 7) >> 3)
74
82
  hashin = a.map {|s|
75
83
  next unless s
@@ -79,41 +87,56 @@ module SRP
79
87
  end
80
88
  "0" * (nlen - shex.length) + shex
81
89
  }.join('')
82
- sha1_hex(hashin).hex % n
90
+ # warn "HASH: #{hashin}"
91
+ sha1_hex(hashin, hash).hex % n
83
92
  end
84
93
 
85
94
  # Multiplier parameter
86
95
  # k = H(N, g) (in SRP-6a)
87
- def calc_k(n, g)
88
- H(n, n, g)
96
+ def calc_k(n, g, hash)
97
+ k1 = H(n, n, g, hash)
98
+ # warn "n: #{n.to_s(16)}"
99
+ # warn "g: #{g.to_s}"
100
+ # warn "k: #{k1.to_s(16)}"
101
+ H(n, n, g, hash)
89
102
  end
90
103
 
91
104
  # Private key (derived from username, raw password and salt)
92
105
  # x = H(salt || H(username || ':' || password))
93
- def calc_x(username, password, salt)
106
+ def calc_x(username, password, salt, hash)
94
107
  spad = if salt.length.odd? then '0' else '' end
95
- sha1_hex(spad + salt + sha1_str([username, password].join(':'))).hex
108
+ x1 = sha1_hex(spad + salt + sha1_str([username, password].join(':')), hash).hex
109
+ # warn "x: #{x1.to_s(16)}"
110
+ sha1_hex(spad + salt + sha1_str([username, password].join(':'), hash), hash).hex
96
111
  end
97
112
 
98
113
  # Random scrambling parameter
99
114
  # u = H(A, B)
100
- def calc_u(xaa, xbb, n)
101
- H(n, xaa, xbb)
115
+ def calc_u(xaa, xbb, n, hash)
116
+ u1 = H(n, xaa, xbb, hash)
117
+ # warn "u: #{u1.to_s(16)}"
118
+ H(n, xaa, xbb, hash)
102
119
  end
103
120
 
104
121
  # Password verifier
105
122
  # v = g^x (mod N)
106
123
  def calc_v(x, n, g)
124
+ v1 = modpow(g,x,n)
125
+ # warn "v: #{v1.to_s(16)}"
107
126
  modpow(g, x, n)
108
127
  end
109
128
 
110
129
  # A = g^a (mod N)
111
130
  def calc_A(a, n, g)
131
+ a1 = modpow(g,a,n)
132
+ # warn "A: #{a1.to_s(16)}"
112
133
  modpow(g, a, n)
113
134
  end
114
135
 
115
136
  # B = g^b + k v (mod N)
116
137
  def calc_B(b, k, v, n, g)
138
+ b1 = (modpow(g, b, n) + k * v) % n
139
+ # warn "B: #{b1.to_s(16)}"
117
140
  (modpow(g, b, n) + k * v) % n
118
141
  end
119
142
 
@@ -126,21 +149,23 @@ module SRP
126
149
  # Server secret
127
150
  # S = (A * v^u) ^ b % N
128
151
  def calc_server_S(aa, b, v, u, n)
152
+ s1 = modpow((modpow(v, u, n) * aa), b, n)
153
+ # warn "S: #{s1.to_s(16)}"
129
154
  modpow((modpow(v, u, n) * aa), b, n)
130
155
  end
131
156
 
132
157
  # M = H(H(N) xor H(g), H(I), s, A, B, K)
133
- def calc_M(username, xsalt, xaa, xbb, xkk, n, g)
134
- hn = sha1_hex("%x" % n).hex
135
- hg = sha1_hex("%x" % g).hex
136
- hxor = "%x" % (hn ^ hg)
137
- hi = sha1_str(username)
138
- return H(n, hxor, hi, xsalt, xaa, xbb, xkk)
158
+ def calc_M1(xaa, xbb, xkk, n, hash)
159
+ m1 = H(n, xaa, xbb, xkk, hash)
160
+ # warn "M1: #{m1.to_s(16)}"
161
+ return H(n, xaa, xbb, xkk, hash)
139
162
  end
140
163
 
141
164
  # H(A, M, K)
142
- def calc_H_AMK(xaa, xmm, xkk, n, g)
143
- H(n, xaa, xmm, xkk)
165
+ def calc_M2(xaa, xmm, xkk, n, hash)
166
+ m2 = H(n, xaa, xmm, xkk, hash)
167
+ # warn "M2: #{m2.to_s(16)}"
168
+ H(n, xaa, xmm, xkk, hash)
144
169
  end
145
170
 
146
171
  def Ng(group)
@@ -311,10 +336,11 @@ module SRP
311
336
  class Verifier
312
337
  attr_reader :N, :g, :k, :A, :B, :b, :S, :K, :M, :H_AMK
313
338
 
314
- def initialize group=1024
339
+ def initialize(group = 1024, hash = 'sha-1')
315
340
  # select modulus (N) and generator (g)
316
- @N, @g = SRP.Ng group
317
- @k = SRP.calc_k(@N, @g)
341
+ @N, @g = SRP.Ng(group)
342
+ @hash = hash
343
+ @k = SRP.calc_k(@N, @g, @hash)
318
344
  end
319
345
 
320
346
  # Initial user creation for the persistance layer.
@@ -322,7 +348,8 @@ module SRP
322
348
  # Returns { <username>, <password verifier>, <salt> }
323
349
  def generate_userauth username, password
324
350
  @salt ||= random_salt
325
- x = SRP.calc_x(username, password, @salt)
351
+ # warn "salt: #{@salt}"
352
+ x = SRP.calc_x(username, password, @salt, @hash)
326
353
  v = SRP.calc_v(x, @N, @g)
327
354
  return {:username => username, :verifier => "%x" % v, :salt => @salt}
328
355
  end
@@ -334,6 +361,7 @@ module SRP
334
361
  # SRP-6a safety check
335
362
  return false if (xaa.to_i(16) % @N) == 0
336
363
  generate_B(xverifier)
364
+ # warn "A: #{xaa}"
337
365
  return {
338
366
  :challenge => {:B => @B, :salt => xsalt},
339
367
  :proof => {:A => xaa, :B => @B, :b => "%x" % @b,
@@ -348,31 +376,35 @@ module SRP
348
376
  @A = proof[:A]
349
377
  @B = proof[:B]
350
378
  @b = proof[:b].to_i(16)
379
+ # warn "b: #{@b}"
380
+
351
381
  username = proof[:I]
352
382
  xsalt = proof[:s]
353
383
  v = proof[:v].to_i(16)
354
384
 
355
- u = SRP.calc_u(@A, @B, @N)
385
+ u = SRP.calc_u(@A, @B, @N, @hash)
356
386
  # SRP-6a safety check
357
387
  return false if u == 0
358
388
 
359
389
  # calculate session key
360
390
  @S = "%x" % SRP.calc_server_S(@A.to_i(16), @b, v, u, @N)
361
- @K = SRP.sha1_hex(@S)
362
391
 
363
- # calculate match
364
- @M = "%x" % SRP.calc_M(username, xsalt, @A, @B, @K, @N, @g)
392
+ @K = SRP.sha1_hex(@S, @hash)
393
+ # warn "K: #{@K}"
365
394
 
395
+ # calculate match
396
+ @M = "%x" % SRP.calc_M1(@A, @B, @K, @N, @hash)
397
+
366
398
  if @M == client_M
367
399
  # authentication succeeded
368
- @H_AMK = "%x" % SRP.calc_H_AMK(@A, @M, @K, @N, @g)
400
+ @H_AMK = "%x" % SRP.calc_M2(@A, @M, @K, @N, @hash)
369
401
  return @H_AMK
370
402
  end
371
403
  return false
372
404
  end
373
405
 
374
406
  def random_salt
375
- "%x" % SRP.bigrand(10).hex
407
+ "%x" % SRP.bigrand(16).hex
376
408
  end
377
409
 
378
410
  def random_bignum
@@ -392,14 +424,17 @@ module SRP
392
424
  class Client
393
425
  attr_reader :N, :g, :k, :a, :A, :S, :K, :M, :H_AMK
394
426
 
395
- def initialize group=1024
427
+ def initialize(group, hash)
396
428
  # select modulus (N) and generator (g)
397
- @N, @g = SRP.Ng group
398
- @k = SRP.calc_k(@N, @g)
429
+ @N, @g = SRP.Ng(group)
430
+ @hash = hash
431
+ @k = SRP.calc_k(@N, @g, @hash)
399
432
  end
400
433
 
401
434
  def start_authentication
402
- generate_A
435
+ a = generate_A
436
+ # warn "A: #{a.to_s(16)}"
437
+ a
403
438
  end
404
439
 
405
440
  # Process initiated authentication challenge.
@@ -410,21 +445,21 @@ module SRP
410
445
  # SRP-6a safety check
411
446
  return false if (bb % @N) == 0
412
447
 
413
- x = SRP.calc_x(username, password, xsalt)
414
- u = SRP.calc_u(@A, xbb, @N)
448
+ x = SRP.calc_x(username, password, xsalt, @hash)
449
+ u = SRP.calc_u(@A, xbb, @N, @hash)
415
450
 
416
451
  # SRP-6a safety check
417
452
  return false if u == 0
418
453
 
419
454
  # calculate session key
420
455
  @S = "%x" % SRP.calc_client_S(bb, @a, @k, x, u, @N, @g)
421
- @K = SRP.sha1_hex(@S)
456
+ @K = SRP.sha1_hex(@S, hash)
422
457
 
423
458
  # calculate match
424
- @M = "%x" % SRP.calc_M(username, xsalt, @A, xbb, @K, @N, @g)
459
+ @M = "%x" % SRP.calc_M1(@A, xbb, @K, @N, @hash)
425
460
 
426
461
  # calculate verifier
427
- @H_AMK = "%x" % SRP.calc_H_AMK(@A, @M, @K, @N, @g)
462
+ @H_AMK = "%x" % SRP.calc_M2(@A, @M, @K, @N, @hash)
428
463
 
429
464
  return @M
430
465
  end
@@ -440,7 +475,8 @@ module SRP
440
475
 
441
476
  def generate_A
442
477
  @a ||= random_bignum
478
+ # warn "a: #{@a}"
443
479
  @A = "%x" % SRP.calc_A(@a, @N, @g)
444
480
  end
445
481
  end # Client
446
- end
482
+ end
@@ -1,5 +1,5 @@
1
1
  module Srp
2
2
  module Rb
3
- VERSION = "1.0.0"
3
+ VERSION = "1.0.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: srp-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-25 00:00:00.000000000 Z
12
+ date: 2013-12-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec