1 29 30 package com.caucho.server.security; 31 32 import com.caucho.config.ConfigException; 33 import com.caucho.util.Base64; 34 import com.caucho.util.CharBuffer; 35 import com.caucho.util.L10N; 36 37 import javax.annotation.PostConstruct; 38 import javax.servlet.ServletContext ; 39 import javax.servlet.ServletException ; 40 import javax.servlet.http.HttpServletRequest ; 41 import javax.servlet.http.HttpServletResponse ; 42 import java.security.MessageDigest ; 43 44 62 public class PasswordDigest { 63 private final L10N L = new L10N(PasswordDigest.class); 64 65 private String _algorithm = "MD5"; 66 private String _format = "base64"; 67 private String _realm = null; 68 private MessageDigest _digest; 69 private byte[] _digestBytes = new byte[256]; 70 private boolean _isOldEncoding; 71 72 75 public void setAlgorithm(String algorithm) 76 { 77 _algorithm = algorithm; 78 } 79 80 83 public String getAlgorithm() 84 { 85 return _algorithm; 86 } 87 88 91 public void setFormat(String format) 92 { 93 _format = format; 94 } 95 96 99 public String getFormat() 100 { 101 return _format; 102 } 103 104 107 public void setRealm(String realm) 108 { 109 _realm = realm; 110 } 111 112 115 public String getRealm() 116 { 117 return _realm; 118 } 119 120 123 public void setOldEncoding(boolean isOldEncoding) 124 { 125 _isOldEncoding = isOldEncoding; 126 } 127 128 131 public void addText(String value) 132 throws ConfigException 133 { 134 int p = value.indexOf('-'); 135 136 if (p > 0) { 137 String algorithm = value.substring(0, p); 138 String format = value.substring(p + 1); 139 140 setAlgorithm(algorithm); 141 setFormat(format); 142 } 143 else if (value.equals("none")) { 144 setAlgorithm(null); 145 setAlgorithm(null); 146 } 147 else 148 throw new ConfigException(L.l("{0} is an illegal algorithm. Expected `none' or `alogorithm-format', for example `MD5-base64'.", value)); 149 } 150 151 154 @PostConstruct 155 synchronized public void init() 156 throws ServletException 157 { 158 if (_algorithm == null) 159 return; 160 161 try { 162 _digest = MessageDigest.getInstance(_algorithm); 163 } catch (Exception e) { 164 throw new ServletException (e); 165 } 166 } 167 168 171 public String getPasswordDigest(String password) 172 throws ServletException 173 { 174 return getPasswordDigest(null, null, null, password, _realm); 175 } 176 177 180 public String getPasswordDigest(String user, String password) 181 throws ServletException 182 { 183 return getPasswordDigest(null, null, null, user, password, _realm); 184 } 185 186 189 public String getPasswordDigest(String user, String password, String realm) 190 throws ServletException 191 { 192 return getPasswordDigest(null, null, null, user, password, realm); 193 } 194 195 208 public String getPasswordDigest(HttpServletRequest request, 209 HttpServletResponse response, 210 ServletContext app, 211 String user, String password) 212 throws ServletException 213 { 214 return getPasswordDigest(request, response, app, user, password, _realm); 215 } 216 217 231 public String getPasswordDigest(HttpServletRequest request, 232 HttpServletResponse response, 233 ServletContext app, 234 String user, String password, String realm) 235 throws ServletException 236 { 237 if (_digest == null) 238 init(); 239 240 try { 241 synchronized (_digest) { 242 _digest.reset(); 243 244 updateDigest(_digest, user, password, realm); 245 246 int len = _digest.digest(_digestBytes, 0, _digestBytes.length); 247 248 return digestToString(_digestBytes, len); 249 } 250 } catch (Exception e) { 251 throw new ServletException (e); 252 } 253 } 254 255 258 protected void updateDigest(MessageDigest digest, 259 String user, String password, String realm) 260 { 261 if (user != null) { 262 addDigestUTF8(digest, user); 263 digest.update((byte) ':'); 264 } 265 266 if (realm != null && ! realm.equals("none")) { 267 addDigestUTF8(digest, realm); 268 digest.update((byte) ':'); 269 } 270 271 addDigestUTF8(digest, password); 272 } 273 274 277 protected static void addDigestUTF8(MessageDigest digest, String string) 278 { 279 if (string == null) 280 return; 281 282 int len = string.length(); 283 for (int i = 0; i < len; i++) { 284 int ch = string.charAt(i); 285 if (ch < 0x80) 286 digest.update((byte) ch); 287 else if (ch < 0x800) { 288 digest.update((byte) (0xc0 + (ch >> 6))); 289 digest.update((byte) (0x80 + (ch & 0x3f))); 290 } 291 else { 292 digest.update((byte) (0xe0 + (ch >> 12))); 293 digest.update((byte) (0x80 + ((ch >> 6) & 0x3f))); 294 digest.update((byte) (0x80 + (ch & 0x3f))); 295 } 296 } 297 } 298 299 302 protected byte[]stringToDigest(String s) 303 { 304 return Base64.decodeToByteArray(s); 305 } 306 307 310 protected String digestToString(byte []digest, int len) 311 { 312 if (! _format.equals("base64")) 313 return digestToHex(digest, len); 314 else if (_isOldEncoding) 315 return digestToOldBase64(digest, len); 316 else 317 return digestToBase64(digest, len); 318 } 319 320 protected static String digestToBase64(byte []digest, int len) 321 { 322 CharBuffer cb = CharBuffer.allocate(); 323 324 Base64.encode(cb, digest, 0, len); 325 326 return cb.close(); 327 } 328 329 protected static String digestToOldBase64(byte []digest, int len) 330 { 331 CharBuffer cb = CharBuffer.allocate(); 332 333 Base64.oldEncode(cb, digest, 0, len); 334 335 return cb.close(); 336 } 337 338 protected static String digestToHex(byte []digest, int len) 339 { 340 CharBuffer cb = CharBuffer.allocate(); 341 342 for (int i = 0; i < len; i++) { 343 int d1 = (digest[i] >> 4) & 0xf; 344 int d2 = digest[i] & 0xf; 345 346 if (d1 >= 10) 347 cb.append((char) (d1 + 'a' - 10)); 348 else 349 cb.append((char) (d1 + '0')); 350 351 if (d2 >= 10) 352 cb.append((char) (d2 + 'a' - 10)); 353 else 354 cb.append((char) (d2 + '0')); 355 } 356 357 return cb.close(); 358 } 359 } 360 | Popular Tags |