Skip to content

Commit 78be7ec

Browse files
Chris HutStephane Landelle
authored andcommitted
Randomized cnonce, close AsyncHttpClient#787
1 parent bd4d3bd commit 78be7ec

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

api/src/main/java/org/asynchttpclient/Realm.java

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.nio.charset.Charset;
2424
import java.security.MessageDigest;
2525
import java.security.NoSuchAlgorithmException;
26+
import java.util.concurrent.ThreadLocalRandom;
2627

2728
import org.asynchttpclient.uri.Uri;
2829
import org.asynchttpclient.util.StringUtils;
@@ -275,6 +276,17 @@ public static class RealmBuilder {
275276
private boolean omitQuery;
276277
private boolean targetProxy;
277278

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+
278290
public String getNtlmDomain() {
279291
return ntlmDomain;
280292
}
@@ -490,14 +502,13 @@ public RealmBuilder clone(Realm clone) {
490502
return this;
491503
}
492504

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);
501512
}
502513

503514
/**
@@ -529,14 +540,7 @@ public RealmBuilder setCharset(Charset charset) {
529540
return this;
530541
}
531542

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) {
540544
StringBuilder sb = StringUtils.stringBuilder();
541545
md.update(sb.append(principal)
542546
.append(":")
@@ -545,7 +549,6 @@ private void newResponse() {
545549
.append(password)
546550
.toString().getBytes(ISO_8859_1));
547551
byte[] ha1 = md.digest();
548-
549552
md.reset();
550553

551554
//HA2 if qop is auth-int is methodName:url:md5(entityBody)
@@ -575,8 +578,9 @@ private void newResponse() {
575578

576579
appendBase16(sb, ha2);
577580
md.update(sb.toString().getBytes(ISO_8859_1));
578-
581+
579582
byte[] digest = md.digest();
583+
md.reset();
580584

581585
response = toHexString(digest);
582586
}
@@ -614,8 +618,9 @@ public Realm build() {
614618

615619
// Avoid generating
616620
if (isNonEmpty(nonce)) {
617-
newCnonce();
618-
newResponse();
621+
MessageDigest md = digestThreadLocal.get();
622+
newCnonce(md);
623+
newResponse(md);
619624
}
620625

621626
return new Realm(scheme, principal, password, realmName, nonce, algorithm, response, qop, nc, cnonce, uri, methodName,

0 commit comments

Comments
 (0)