Java/Security/MD5 String

Материал из Java эксперт
Перейти к: навигация, поиск

Encode an MD5 digest into a String.

   
/*
 * 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.
 * <p>
 * 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);
    }

}





Get MD5 Base64

   
/*
 * $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));
    }
}





Security Utils

   
/**
 * 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: <code><pre>
     * Base64.encodeBytes(currentTimeMS + &quot;:&quot;
     *         + md5String(currentTimeMS + &quot;:&quot; + secretKey))
     * </pre></code>
     * 
     * @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);
    }
}





Use MD5 to encrypt a string

 
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();
    }
}