23
23
import java .nio .charset .Charset ;
24
24
import java .security .MessageDigest ;
25
25
import java .security .NoSuchAlgorithmException ;
26
+ import java .util .concurrent .ThreadLocalRandom ;
26
27
27
28
import org .asynchttpclient .uri .Uri ;
28
29
import org .asynchttpclient .util .StringUtils ;
@@ -275,6 +276,17 @@ public static class RealmBuilder {
275
276
private boolean omitQuery ;
276
277
private boolean targetProxy ;
277
278
279
+ private static final ThreadLocal <MessageDigest > digestThreadLocal = new ThreadLocal <MessageDigest >() {
280
+ @ Override
281
+ protected MessageDigest initialValue () {
282
+ try {
283
+ return MessageDigest .getInstance ("MD5" );
284
+ } catch (NoSuchAlgorithmException e ) {
285
+ throw new RuntimeException (e );
286
+ }
287
+ }
288
+ };
289
+
278
290
public String getNtlmDomain () {
279
291
return ntlmDomain ;
280
292
}
@@ -490,14 +502,13 @@ public RealmBuilder clone(Realm clone) {
490
502
return this ;
491
503
}
492
504
493
- private void newCnonce () {
494
- try {
495
- MessageDigest md = MessageDigest .getInstance ("MD5" );
496
- byte [] b = md .digest (String .valueOf (System .currentTimeMillis ()).getBytes (ISO_8859_1 ));
497
- cnonce = toHexString (b );
498
- } catch (Exception e ) {
499
- throw new SecurityException (e );
500
- }
505
+ private void newCnonce (MessageDigest md ) {
506
+ byte [] b = new byte [8 ];
507
+ ThreadLocalRandom .current ().nextBytes (b );
508
+ b = md .digest (b );
509
+ md .reset ();
510
+
511
+ cnonce = toHexString (b );
501
512
}
502
513
503
514
/**
@@ -529,14 +540,7 @@ public RealmBuilder setCharset(Charset charset) {
529
540
return this ;
530
541
}
531
542
532
- private void newResponse () {
533
- MessageDigest md = null ;
534
- try {
535
- md = MessageDigest .getInstance ("MD5" );
536
- } catch (NoSuchAlgorithmException e ) {
537
- throw new SecurityException (e );
538
- }
539
-
543
+ private void newResponse (MessageDigest md ) {
540
544
StringBuilder sb = StringUtils .stringBuilder ();
541
545
md .update (sb .append (principal )
542
546
.append (":" )
@@ -545,7 +549,6 @@ private void newResponse() {
545
549
.append (password )
546
550
.toString ().getBytes (ISO_8859_1 ));
547
551
byte [] ha1 = md .digest ();
548
-
549
552
md .reset ();
550
553
551
554
//HA2 if qop is auth-int is methodName:url:md5(entityBody)
@@ -575,8 +578,9 @@ private void newResponse() {
575
578
576
579
appendBase16 (sb , ha2 );
577
580
md .update (sb .toString ().getBytes (ISO_8859_1 ));
578
-
581
+
579
582
byte [] digest = md .digest ();
583
+ md .reset ();
580
584
581
585
response = toHexString (digest );
582
586
}
@@ -614,8 +618,9 @@ public Realm build() {
614
618
615
619
// Avoid generating
616
620
if (isNonEmpty (nonce )) {
617
- newCnonce ();
618
- newResponse ();
621
+ MessageDigest md = digestThreadLocal .get ();
622
+ newCnonce (md );
623
+ newResponse (md );
619
624
}
620
625
621
626
return new Realm (scheme , principal , password , realmName , nonce , algorithm , response , qop , nc , cnonce , uri , methodName ,
0 commit comments