Java/Security/MD5 String
Содержание
Encode an MD5 digest into a String.
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* Encode an MD5 digest into a String.*
* The 128 bit MD5 hash is converted into a 32 character long String. * Each character of the String is the hexadecimal representation of 4 bits * of the digest. * * @author Remy Maucherat * @version $Revision: 515 $ $Date: 2008-03-17 22:02:23 +0100 (Mon, 17 Mar 2008) $ */ public final class MD5Encoder { // ----------------------------------------------------- Instance Variables private static final char[] hexadecimal = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; // --------------------------------------------------------- Public Methods /** * Encodes the 128 bit (16 bytes) MD5 into a 32 character String. * * @param binaryData Array containing the digest * @return Encoded MD5, or null if encoding failed */ public String encode( byte[] binaryData ) { if (binaryData.length != 16) return null; char[] buffer = new char[32]; for (int i=0; i<16; i++) { int low = (int) (binaryData[i] & 0x0f); int high = (int) ((binaryData[i] & 0xf0) >> 4); buffer[i*2] = hexadecimal[high]; buffer[i*2 + 1] = hexadecimal[low]; } return new String(buffer); } } </source>
Get MD5 Base64
<source lang="java">
/*
* $Header: /cvsroot/mvnforum/mvnforum/contrib/phpbb2mvnforum/src/org/mvnforum/util/MD5.java,v 1.6 2007/01/15 10:27:31 dungbtm Exp $ * $Author: dungbtm $ * $Revision: 1.6 $ * $Date: 2007/01/15 10:27:31 $ * * * * Copyright (C) 2002-2007 by MyVietnam.net * * All copyright notices regarding mvnForum MUST remain * intact in the scripts and in the outputted HTML. * The "powered by" text/logo with a link back to * http://www.mvnForum.ru and http://www.MyVietnam.net in * the footer of the pages MUST remain visible when the pages * are viewed on the internet or intranet. * * This program 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 * any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Support can be obtained from support forums at: * http://www.mvnForum.ru/mvnforum/index * * Correspondence and Marketing Questions can be sent to: * info at MyVietnam net * * @author: */
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import sun.misc.BASE64Encoder; // // The JavaReference.ru Software License, Version 1.0 // Copyright (c) 2002-2005 JavaReference.ru. All rights reserved. // // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // 3. The end-user documentation included with the redistribution, if any, must // include the following acknowlegement: // // "This product includes software developed by the Javareference.ru // (http://www.javareference.ru/)." // // Alternately, this acknowlegement may appear in the software itself, if and // wherever such third-party acknowlegements normally appear. // // 4. The names "JavaReference" and "Javareference.ru", must not be used to // endorse or promote products derived from this software without prior written // permission. For written permission, please contact webmaster@javareference.ru. // // 5. Products derived from this software may not be called "Javareference" nor may // "Javareference" appear in their names without prior written permission of // Javareference.ru. // // THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL // JAVAREFERENCE.ru OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // // Software from this site consists of contributions made by various individuals // on behalf of Javareference.ru. For more information on Javareference.ru, // please see http://www.javareference.ru // /**
* @author anandh */
public class MD5 {
static char[] carr = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; public static String getBase64FromHEX(String input) { byte barr[] = new byte[16]; int bcnt = 0; for (int i = 0; i < 32; i += 2) { char c1 = input.charAt(i); char c2 = input.charAt(i + 1); int i1 = intFromChar(c1); int i2 = intFromChar(c2); barr[bcnt] = 0; barr[bcnt] |= (byte) ((i1 & 0x0F) << 4); barr[bcnt] |= (byte) (i2 & 0x0F); bcnt++; } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(barr); } public static synchronized String getMD5_Base64(String input) { // please note that we dont use digest, because if we // cannot get digest, then the second time we have to call it // again, which will fail again MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); } catch (Exception ex) { ex.printStackTrace(); } if (digest == null) return input; // now everything is ok, go ahead try { digest.update(input.getBytes("UTF-8")); } catch (java.io.UnsupportedEncodingException ex) { ex.printStackTrace(); } byte[] rawData = digest.digest(); BASE64Encoder bencoder = new BASE64Encoder(); return bencoder.encode(rawData); } private static int intFromChar(char c) { char clower = Character.toLowerCase(c); for (int i = 0; i < carr.length; i++) { if (clower == carr[i]) { return i; } } return 0; } public static void main(String[] args) { //String password = args[0]; String password = "test"; MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } try { digest.update(password.getBytes("UTF-8")); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } byte[] rawData = digest.digest(); StringBuffer printable = new StringBuffer(); for (int i = 0; i < rawData.length; i++) { printable.append(carr[((rawData[i] & 0xF0) >> 4)]); printable.append(carr[(rawData[i] & 0x0F)]); } String phpbbPassword = printable.toString(); System.out.println("PHPBB : " + phpbbPassword); System.out.println("MVNFORUM : " + getMD5_Base64(password)); System.out.println("PHPBB->MVNFORUM : " + getBase64FromHEX(phpbbPassword)); }
}
</source>
Security Utils
<source lang="java">
/**
* Copyright 2005-2008 Noelios Technologies. * * The contents of this file are subject to the terms of the following open * source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the LGPL 3.0 license at * http://www.gnu.org/licenses/lgpl-3.0.html * * You can obtain a copy of the LGPL 2.1 license at * http://www.gnu.org/licenses/lgpl-2.1.html * * You can obtain a copy of the CDDL 1.0 license at * http://www.sun.ru/cddl/cddl.html * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royaltee free commercial license with less * limitations, transferable or non-transferable, directly at * http://www.noelios.ru/products/restlet-engine * * Restlet is a registered trademark of Noelios Technologies. */
import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; /**
* Security data manipulation utilities. * * @author Jerome Louvel */
public class SecurityUtils {
/** * General regex pattern to extract comma separated name-value components. * This pattern captures one name and value per match(), and is repeatedly * applied to the input string to extract all components. Must handle both * quoted and unquoted values as RFC2617 isn"t consistent in this respect. * Pattern is immutable and thread-safe so reuse one static instance. */ private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); /** * Generates a nonce as recommended in section 3.2.1 of RFC-2617, but* without the ETag field. The format is:
* Base64.encodeBytes(currentTimeMS + ":"
* + md5String(currentTimeMS + ":" + secretKey))
*
* * @param secretKey * a secret value known only to the creator of the nonce. It"s * inserted into the nonce, and can be used later to validate the * nonce. */ public static String makeNonce(String secretKey) { final long currentTimeMS = System.currentTimeMillis(); return Base64.encode((currentTimeMS + ":" + toMd5(currentTimeMS + ":" + secretKey)).getBytes(), true); } /** * Converts a source string to its HMAC/SHA-1 value. * * @param source * The source string to convert. * @param secretKey * The secret key to use for conversion. * @return The HMac value of the source string. */ public static byte[] toHMac(String source, String secretKey) { byte[] result = null; try { // Create the HMAC/SHA1 key final SecretKeySpec signingKey = new SecretKeySpec(secretKey .getBytes(), "HmacSHA1"); // Create the message authentication code (MAC) final Mac mac = Mac.getInstance("HmacSHA1"); mac.init(signingKey); // Compute the HMAC value result = mac.doFinal(source.getBytes()); } catch (NoSuchAlgorithmException nsae) { throw new RuntimeException( "Could not find the SHA-1 algorithm. HMac conversion failed.", nsae); } catch (InvalidKeyException ike) { throw new RuntimeException( "Invalid key exception detected. HMac conversion failed.", ike); } return result; } /** * Returns the MD5 digest of the target string. Target is decoded to bytes * using the US-ASCII charset. The returned hexadecimal String always * contains 32 lowercase alphanumeric characters. For example, if target is * "HelloWorld", this method returns "68e109f0f40ca72a15e05cc22786f8e6". * * @param target * The string to encode. * @return The MD5 digest of the target string. */ public static String toMd5(String target) { try { return toMd5(target, "US-ASCII"); } catch (UnsupportedEncodingException uee) { // Unlikely, US-ASCII comes with every JVM throw new RuntimeException( "US-ASCII is an unsupported encoding, unable to compute MD5"); } } /** * Returns the MD5 digest of target string. Target is decoded to bytes using * the named charset. The returned hexadecimal String always contains 32 * lowercase alphanumeric characters. For example, if target is * "HelloWorld", this method returns "68e109f0f40ca72a15e05cc22786f8e6". * * @param target * The string to encode. * @param charsetName * The character set. * @return The MD5 digest of the target string. * * @throws UnsupportedEncodingException */ public static String toMd5(String target, String charsetName) throws UnsupportedEncodingException { try { final byte[] md5 = MessageDigest.getInstance("MD5").digest( target.getBytes(charsetName)); final char[] md5Chars = new char[32]; int i = 0; for (final byte b : md5) { md5Chars[i++] = HEXDIGITS[(b >> 4) & 0xF]; md5Chars[i++] = HEXDIGITS[b & 0xF]; } return new String(md5Chars); } catch (NoSuchAlgorithmException nsae) { throw new RuntimeException( "No MD5 algorithm, unable to compute MD5"); } } /** * Returns the SHA1 digest of the target string. Target is decoded to bytes * using the US-ASCII charset. * * @param target * The string to encode. * @return The MD5 digest of the target string. */ public static String toSha1(String target) { try { return toSha1(target, "US-ASCII"); } catch (UnsupportedEncodingException uee) { // Unlikely, US-ASCII comes with every JVM throw new RuntimeException( "US-ASCII is an unsupported encoding, unable to compute SHA1"); } } /** * Returns the SHA1 digest of target string. Target is decoded to bytes * using the named charset. * * @param target * The string to encode. * @param charsetName * The character set. * @return The SHA1 digest of the target string. * * @throws UnsupportedEncodingException */ public static String toSha1(String target, String charsetName) throws UnsupportedEncodingException { try { return Base64.encode(MessageDigest.getInstance("SHA1").digest( target.getBytes(charsetName)), false); } catch (NoSuchAlgorithmException nsae) { throw new RuntimeException( "No SHA1 algorithm, unable to compute SHA1"); } }
} /**
* Copyright 2005-2008 Noelios Technologies. * * The contents of this file are subject to the terms of the following open * source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the LGPL 3.0 license at * http://www.gnu.org/licenses/lgpl-3.0.html * * You can obtain a copy of the LGPL 2.1 license at * http://www.gnu.org/licenses/lgpl-2.1.html * * You can obtain a copy of the CDDL 1.0 license at * http://www.sun.ru/cddl/cddl.html * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royaltee free commercial license with less * limitations, transferable or non-transferable, directly at * http://www.noelios.ru/products/restlet-engine * * Restlet is a registered trademark of Noelios Technologies. */
/**
* Minimal but fast Base64 codec. * * @author Ray Waldin (ray@waldin.net) */ class Base64 { /** alphabet used for encoding bytes into base64 */ private static final char[] BASE64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray(); /** * decoding involves replacing each character with the character"s value, or * position, from the above alphabet, and this table makes such lookups * quick and easy. Couldn"t help myself with the corny name :) */ private static final byte[] DECODER_RING = new byte[128]; static { Arrays.fill(DECODER_RING, (byte) -1); int i = 0; for (final char c : BASE64_DIGITS) { DECODER_RING[c] = (byte) i++; } DECODER_RING["="] = 0; } private final static int byteAt(byte[] data, int block, int off) { return unsign(data[(block * 3) + off]); } /** * Decodes a base64 string into bytes. Newline characters found at block * boundaries will be ignored. * * @param encodedString * The string to decode. * @return The decoded byte array. */ public static byte[] decode(String encodedString) { final char[] chars = encodedString.toCharArray(); // prepare to ignore newline chars int newlineCount = 0; for (final char c : chars) { switch (c) { case "\r": case "\n": newlineCount++; break; default: } } final int len = chars.length - newlineCount; int numBytes = ((len + 3) / 4) * 3; // fix up length relative to padding if (len > 1) { if (chars[chars.length - 2] == "=") { numBytes -= 2; } else if (chars[chars.length - 1] == "=") { numBytes--; } } final byte[] result = new byte[numBytes]; int newlineOffset = 0; // decode each block of 4 chars into 3 bytes for (int i = 0; i < (len + 3) / 4; ++i) { int charOffset = newlineOffset + (i * 4); final char c1 = chars[charOffset++]; final char c2 = chars[charOffset++]; final char c3 = chars[charOffset++]; final char c4 = chars[charOffset++]; if (!(validChar(c1) && validChar(c2) && validChar(c3) && validChar(c4))) { throw new IllegalArgumentException( "Invalid Base64 character in block: "" + c1 + c2 + c3 + c4 + """); } // pack final int x = DECODER_RING[c1] << 18 | DECODER_RING[c2] << 12 | (c3 == "=" ? 0 : DECODER_RING[c3] << 6) | (c4 == "=" ? 0 : DECODER_RING[c4]); // unpack int byteOffset = i * 3; result[byteOffset++] = (byte) (x >> 16); if (c3 != "=") { result[byteOffset++] = (byte) ((x >> 8) & 0xFF); if (c4 != "=") { result[byteOffset++] = (byte) (x & 0xFF); } } // skip newlines after block outer: while (chars.length > charOffset) { switch (chars[charOffset++]) { case "\r": case "\n": newlineOffset++; break; default: break outer; } } } return result; } /** * Encodes an entire byte array into a Base64 string, with optional newlines * after every 76 characters. * * @param bytes * The byte array to encode. * @param newlines * Indicates whether or not newlines are desired. * @return The encoded string. */ public static String encode(byte[] bytes, boolean newlines) { return encode(bytes, 0, bytes.length, newlines); } /** * Encodes specified bytes into a Base64 string, with optional newlines * after every 76 characters. * * @param bytes * The byte array to encode. * @param off * The starting offset. * @param len * The number of bytes to encode. * @param newlines * Indicates whether or not newlines are desired. * * @return The encoded string. */ public static String encode(byte[] bytes, int off, int len, boolean newlines) { final char[] output = new char[(((len + 2) / 3) * 4) + (newlines ? len / 43 : 0)]; int pos = 0; // encode each block of 3 bytes into 4 chars for (int i = 0; i < (len + 2) / 3; ++i) { int pad = 0; if (len + 1 < (i + 1) * 3) { // two trailing "="s pad = 2; } else if (len < (i + 1) * 3) { // one trailing "=" pad = 1; } // pack final int x = (byteAt(bytes, i, off) << 16) | (pad > 1 ? 0 : (byteAt(bytes, i, off + 1) << 8)) | (pad > 0 ? 0 : (byteAt(bytes, i, off + 2))); // unpack output[pos++] = BASE64_DIGITS[x >> 18]; output[pos++] = BASE64_DIGITS[(x >> 12) & 0x3F]; output[pos++] = pad > 1 ? "=" : BASE64_DIGITS[(x >> 6) & 0x3F]; output[pos++] = pad > 0 ? "=" : BASE64_DIGITS[x & 0x3F]; if (newlines && ((i + 1) % 19 == 0)) { output[pos++] = "\n"; } } return new String(output, 0, pos); } private final static int unsign(byte b) { return b < 0 ? b + 256 : b; } private final static boolean validChar(char c) { return (c < 128) && (DECODER_RING[c] != -1); }
}
</source>
Use MD5 to encrypt a string
<source lang="java">
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class MD5 {
private static MessageDigest digester; static { try { digester = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public static String crypt(String str) { if (str == null || str.length() == 0) { throw new IllegalArgumentException("String to encript cannot be null or zero length"); } digester.update(str.getBytes()); byte[] hash = digester.digest(); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < hash.length; i++) { if ((0xff & hash[i]) < 0x10) { hexString.append("0" + Integer.toHexString((0xFF & hash[i]))); } else { hexString.append(Integer.toHexString(0xFF & hash[i])); } } return hexString.toString(); }
}
</source>