passworddigest.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 365 行

JAVA
365
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.server.security;import com.caucho.config.ConfigException;import com.caucho.util.Base64;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import javax.annotation.PostConstruct;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.security.MessageDigest;/** * Calculates a digest for the user and password. * * <p>If the realm is missing, the digest will calculate: * <code><pre> * MD5(user + ':' + password) * </pre></code> * * <p>If the realm is specified, the digest will calculate: * <code><pre> * MD5(user + ':' + realm + ':' + password) * </pre></code> * * <p>The second version matches the way HTTP digest authentication * is handled, so it is the preferred method for storing passwords. * * <p>The returned result is the base64 encoding of the digest. */public class PasswordDigest {  private final L10N L = new L10N(PasswordDigest.class);    private String _algorithm = "MD5";  private String _format = "base64";  private String _realm = null;  private MessageDigest _digest;  private byte[] _digestBytes = new byte[256];  private boolean _isOldEncoding;    /**   * Returns the message digest algorithm.   */  public void setAlgorithm(String algorithm)  {    _algorithm = algorithm;  }    /**   * Returns the message digest algorithm.   */  public String getAlgorithm()  {    return _algorithm;  }    /**   * Set the message digest format (base64 or hex).   */  public void setFormat(String format)  {    _format = format;  }    /**   * Returns the message digest format (base64 or hex).   */  public String getFormat()  {    return _format;  }    /**   * Set the message digest default realm   */  public void setRealm(String realm)  {    _realm = realm;  }    /**   * Returns the message digest default realm.   */  public String getRealm()  {    return _realm;  }  /**   * Sets true for the old, buggy encoding.   */  public void setOldEncoding(boolean isOldEncoding)  {    _isOldEncoding = isOldEncoding;  }  /**   * Sets the algorithm for bean-style init.   */  public void addText(String value)    throws ConfigException  {    int p = value.indexOf('-');    if (p > 0) {      String algorithm = value.substring(0, p);      String format = value.substring(p + 1);      setAlgorithm(algorithm);      setFormat(format);    }    else if (value.equals("none")) {      setAlgorithm(null);      setAlgorithm(null);    }    else      throw new ConfigException(L.l("{0} is an illegal algorithm.  Expected `none' or `alogorithm-format', for example `MD5-base64'.", value));  }  /**   * Initialize the digest.   */  @PostConstruct  synchronized public void init()    throws ServletException  {    if (_algorithm == null)      return;        try {      _digest = MessageDigest.getInstance(_algorithm);    } catch (Exception e) {      throw new ServletException(e);    }  }  /**   * Returns the digest of the password   */  public String getPasswordDigest(String password)    throws ServletException  {    return getPasswordDigest(null, null, null, password, _realm);  }  /**   * Returns the digest of the user/password   */  public String getPasswordDigest(String user, String password)    throws ServletException  {    return getPasswordDigest(null, null, null, user, password, _realm);  }  /**   * Returns the digest of the user/password   */  public String getPasswordDigest(String user, String password, String realm)    throws ServletException  {    return getPasswordDigest(null, null, null, user, password, realm);  }    /**   * Returns the digest of the user/password   *   * <p>The default implementation returns the digest of   * <b>user:password</b> or <b>user:realm:password</b> if a   * default realm has been configured.   *   * @param request the http request   * @param response the http response   * @param app the servlet context   * @param user the user name   * @param password the cleartext password   */  public String getPasswordDigest(HttpServletRequest request,                                  HttpServletResponse response,                                  ServletContext app,                                  String user, String password)    throws ServletException  {    return getPasswordDigest(request, response, app, user, password, _realm);  }    /**   * Returns the digest of the user/password   *   * <p>The default implementation returns the digest of   * <b>user:realm:password</b>.  If the realm is null, it will use   * <b>user:password</b>.   *   * @param request the http request   * @param response the http response   * @param app the servlet context   * @param user the user name   * @param password the cleartext password   * @param realm the security realm   */  public String getPasswordDigest(HttpServletRequest request,                                  HttpServletResponse response,                                  ServletContext app,                                  String user, String password, String realm)    throws ServletException  {    if (_digest == null)      init();        try {      synchronized (_digest) {        _digest.reset();	updateDigest(_digest, user, password, realm);        int len = _digest.digest(_digestBytes, 0, _digestBytes.length);        return digestToString(_digestBytes, len);      }    } catch (Exception e) {      throw new ServletException(e);    }  }  /**   * Updates the digest based on the user:realm:password   */  protected void updateDigest(MessageDigest digest,			      String user, String password, String realm)  {    if (user != null) {      addDigestUTF8(digest, user);      digest.update((byte) ':');    }	    if (realm != null && ! realm.equals("none")) {      addDigestUTF8(digest, realm);      digest.update((byte) ':');    }	    addDigestUTF8(digest, password);  }  /**   * Adds the string to the digest using a UTF8 encoding.   */  protected static void addDigestUTF8(MessageDigest digest, String string)  {    if (string == null)      return;        int len = string.length();    for (int i = 0; i < len; i++) {      int ch = string.charAt(i);      if (ch < 0x80)        digest.update((byte) ch);      else if (ch < 0x800) {        digest.update((byte) (0xc0 + (ch >> 6)));        digest.update((byte) (0x80 + (ch & 0x3f)));      }      else {        digest.update((byte) (0xe0 + (ch >> 12)));        digest.update((byte) (0x80 + ((ch >> 6) & 0x3f)));        digest.update((byte) (0x80 + (ch & 0x3f)));      }    }  }  /**   * Convert the string to a digest byte array.   */  protected byte[]stringToDigest(String s)  {    return Base64.decodeToByteArray(s);  }    /**   * Convert the digest byte array to a string.   */  protected String digestToString(byte []digest, int len)  {    if (! _format.equals("base64"))      return digestToHex(digest, len);    else if (_isOldEncoding)      return digestToOldBase64(digest, len);    else      return digestToBase64(digest, len);  }    protected static String digestToBase64(byte []digest, int len)  {    CharBuffer cb = CharBuffer.allocate();    Base64.encode(cb, digest, 0, len);    return cb.close();  }    protected static String digestToOldBase64(byte []digest, int len)  {    CharBuffer cb = CharBuffer.allocate();    Base64.oldEncode(cb, digest, 0, len);    return cb.close();  }    protected static String digestToHex(byte []digest, int len)  {    CharBuffer cb = CharBuffer.allocate();    for (int i = 0; i < len; i++) {      int d1 = (digest[i] >> 4) & 0xf;      int d2 = digest[i] & 0xf;      if (d1 >= 10)        cb.append((char) (d1 + 'a' - 10));      else        cb.append((char) (d1 + '0'));            if (d2 >= 10)        cb.append((char) (d2 + 'a' - 10));      else        cb.append((char) (d2 + '0'));    }    return cb.close();  }  public String toString()  {    return getClass().getSimpleName() + "[]";  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?