/** * Generate a unique token. The token is generated according to the * following pattern. NOnceToken = Base64 ( MD5 ( client-IP ":" * time-stamp ":" private-key ) ). * * @param request HTTP Servlet request */ protected String generateNonce(Request request) { long currentTime = System.currentTimeMillis(); synchronized (lastTimestampLock) { if (currentTime > lastTimestamp) { lastTimestamp = currentTime; } else { currentTime = ++lastTimestamp; } } String ipTimeKey = request.getRemoteAddr() + ":" + currentTime + ":" + getKey(); byte[] buffer = ConcurrentMessageDigest.digestMD5( ipTimeKey.getBytes(B2CConverter.ISO_8859_1)); String nonce = currentTime + ":" + MD5Encoder.encode(buffer); NonceInfo info = new NonceInfo(currentTime, getNonceCountWindowSize()); synchronized (nonces) { nonces.put(nonce, info); } return nonce; }
public Principal authenticate(Realm realm) { // Second MD5 digest used to calculate the digest : // MD5(Method + ":" + uri) String a2 = method + ":" + uri; byte[] buffer = ConcurrentMessageDigest.digestMD5( a2.getBytes(B2CConverter.ISO_8859_1)); String md5a2 = MD5Encoder.encode(buffer); return realm.authenticate(userName, response, nonce, nc, cnonce, qop, realmName, md5a2); }
/** * Return the digest associated with given principal's user name. */ protected String getDigest(String username, String realmName) { if (md5Helper == null) { try { md5Helper = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { log.error("Couldn't get MD5 digest: ", e); throw new IllegalStateException(e.getMessage()); } } if (hasMessageDigest()) { // Use pre-generated digest return getPassword(username); } String digestValue = username + ":" + realmName + ":" + getPassword(username); byte[] valueBytes = null; try { valueBytes = digestValue.getBytes(getDigestCharset()); } catch (UnsupportedEncodingException uee) { log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); throw new IllegalArgumentException(uee.getMessage()); } byte[] digest = null; // Bugzilla 32137 synchronized(md5Helper) { digest = md5Helper.digest(valueBytes); } return MD5Encoder.encode(digest); }
private String buildDigestResponse(String nonce) { String ncString = String.format("%1$08x", Integer.valueOf(nonceCount.incrementAndGet())); String cnonce = "cnonce"; String response = MD5A1 + ":" + nonce + ":" + ncString + ":" + cnonce + ":" + QOP + ":" + MD5A2; String md5response = MD5Encoder.encode( ConcurrentMessageDigest.digest("MD5", response.getBytes())); StringBuilder auth = new StringBuilder(); auth.append("Digest username=\""); auth.append(USER); auth.append("\", realm=\""); auth.append(REALM); auth.append("\", nonce=\""); auth.append(nonce); auth.append("\", uri=\""); auth.append(CONTEXT_PATH + URI); auth.append("\", opaque=\""); auth.append(authenticator.getOpaque()); auth.append("\", response=\""); auth.append(md5response); auth.append("\""); auth.append(", qop="); auth.append(QOP); auth.append(", nc="); auth.append(ncString); auth.append(", cnonce=\""); auth.append(cnonce); auth.append("\""); return auth.toString(); }
public TesterRunnable(int id, int requestCount) throws Exception { this.requestCount = requestCount; path = "http://localhost:" + getPort() + CONTEXT_PATH + URI; // Make the first request as we need the Digest challenge to obtain // the server nonce Map<String,List<String>> respHeaders = new HashMap<String,List<String>>(); getUrl(path, new ByteChunk(), respHeaders); nonce = TestDigestAuthenticator.getNonce(respHeaders); opaque = TestDigestAuthenticator.getOpaque(respHeaders); cnonce = "cnonce" + id; reqHeaders = new HashMap<String,List<String>>(); authHeader = new ArrayList<String>(); reqHeaders.put(CLIENT_AUTH_HEADER, authHeader); digester = MessageDigest.getInstance("MD5"); encoder = new MD5Encoder(); String a1 = USER + ":" + REALM + ":" + PWD; String a2 = "GET:" + CONTEXT_PATH + URI; md5a1 = encoder.encode(digester.digest(a1.getBytes())); md5a2 = encoder.encode(digester.digest(a2.getBytes())); }
private static String digest(String input) throws NoSuchAlgorithmException { // This is slow but should be OK as this is only a test MessageDigest md5 = MessageDigest.getInstance("MD5"); MD5Encoder encoder = new MD5Encoder(); md5.update(input.getBytes()); return encoder.encode(md5.digest()); }
/** * Return the Principal associated with the specified username, which * matches the digest calculated using the given parameters using the * method described in RFC 2069; otherwise return <code>null</code>. * * @param username Username of the Principal to look up * @param clientDigest Digest which has been submitted by the client * @param nonce Unique (or supposedly unique) token which has been used * for this request * @param realm Realm name * @param md5a2 Second MD5 digest used to calculate the digest : * MD5(Method + ":" + uri) */ @Override public Principal authenticate(String username, String clientDigest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2) { // In digest auth, digests are always lower case String md5a1 = getDigest(username, realm); if (md5a1 == null) return null; md5a1 = md5a1.toLowerCase(Locale.ENGLISH); String serverDigestValue; if (qop == null) { serverDigestValue = md5a1 + ":" + nonce + ":" + md5a2; } else { serverDigestValue = md5a1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + md5a2; } byte[] valueBytes = null; try { valueBytes = serverDigestValue.getBytes(getDigestCharset()); } catch (UnsupportedEncodingException uee) { log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); throw new IllegalArgumentException(uee.getMessage()); } String serverDigest = null; // Bugzilla 32137 synchronized(md5Helper) { serverDigest = MD5Encoder.encode(md5Helper.digest(valueBytes)); } if (log.isDebugEnabled()) { log.debug("Digest : " + clientDigest + " Username:" + username + " ClientSigest:" + clientDigest + " nonce:" + nonce + " nc:" + nc + " cnonce:" + cnonce + " qop:" + qop + " realm:" + realm + "md5a2:" + md5a2 + " Server digest:" + serverDigest); } if (serverDigest.equals(clientDigest)) { return getPrincipal(username); } return null; }
private static String digest(String input) { return MD5Encoder.encode( ConcurrentMessageDigest.digestMD5(input.getBytes())); }