package org.jboss.seam.security.digest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.jboss.seam.util.Hex; /** * Digest-related utility methods, adapted from Acegi and Apache Commons. * * @author Shane Bryzak */ public class DigestUtils { public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm, String password, String httpMethod, String uri, String qop, String nonce, String nc, String cnonce) throws IllegalArgumentException { String a1Md5 = null; String a2 = httpMethod + ":" + uri; String a2Md5 = new String(DigestUtils.md5Hex(a2)); if (passwordAlreadyEncoded) { a1Md5 = password; } else { a1Md5 = encodePasswordInA1Format(username, realm, password); } String digest; if (qop == null) { // as per RFC 2069 compliant clients (also reaffirmed by RFC 2617) digest = a1Md5 + ":" + nonce + ":" + a2Md5; } else if ("auth".equals(qop)) { // As per RFC 2617 compliant clients digest = a1Md5 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + a2Md5; } else { throw new IllegalArgumentException("This method does not support a qop: '" + qop + "'"); } String digestMd5 = new String(DigestUtils.md5Hex(digest)); return digestMd5; } public static String encodePasswordInA1Format(String username, String realm, String password) { String a1 = username + ":" + realm + ":" + password; String a1Md5 = new String(DigestUtils.md5Hex(a1)); return a1Md5; } public static String md5Hex(String value) { try { MessageDigest md = MessageDigest.getInstance("MD5"); return new String(Hex.encodeHex(md.digest(value.getBytes()))); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Invalid algorithm"); } } }