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 + -
显示快捷键?