blob: 743c73c4b3f6711b5988733f72eb33a40a27118c [file] [log] [blame]
/* Copyright (c) 2001-2009, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS 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 HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR 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.
*/
package org.hsqldb.lib;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Provides a static utility interface to an MD5 digest algorithm
* obtained through the java.security.MessageDigest spi. <p>
*
* Database end-users may wish to access the services of this class
* to provide, for instance, application user lookup tables with
* one-way password encryption. For example: <p>
*
* <pre>
* -- DDL
* CREATE TABLE USERS(UID INTEGER IDENTITY, UNAME VARCHAR, UPASS VARCHAR, UNIQUE(UNAME))
* CREATE FUNCTION MD5(VARCHAR(100)) RETURNS VARCHAR(16) LANGUAGE JAVA EXTERNAL NAME "org.hsqldb.lib.MD5.encode"
*
* -- DML & DQL
* INSERT INTO USERS(UNAME, UPASS) VALUES('joe', MD5('passwd'))
* UPDATE USERS SET UPASS = MD5('newpasswd') WHERE UNAME = 'joe' AND UPASS = MD5('oldpasswd')
* SELECT UID FROM USERS WHERE UNAME = 'joe' AND UPASS = MD5('logonpasswd')
* </pre>
*
* <b>NOTE:</b> <p>
*
* Although it is possible that a particular JVM / application installation may
* encounter NoSuchAlgorithmException when attempting to get a jce MD5 message
* digest generator, the likelyhood is very small for almost all JDK/JRE 1.1
* and later JVM implementations, as the Sun java.security package has come,
* by default, with a jce MD5 message digest generator since JDK 1.1 was
* released. The HSLQLDB project could have provided an MD5 implementation to
* guarantee presence, but this class is much more lightweight and still allows
* clients to install / use custom implementations through the
* java.security.MessageDigest spi, for instance if there is no service
* provided by default under the target JVM of choice or if a client has
* developed / provides, say, a faster MD5 message digest implementation.
* In short, this class is a convenience that allows HSQLDB SQL Function and
* Stored Procedure style access to any underlying MD5 message digest algorithm
* obtained via the java.security.MessageDigest spi
*
* @author boucherb@users.sourceforge.net
* @version 1.9.0
* @since 1.9.0
*/
public final class MD5 {
/**
* The jce MD5 message digest generator.
*/
private static MessageDigest md5;
/**
* Retrieves a hexidecimal character sequence representing the MD5
* digest of the specified character sequence, using the specified
* encoding to first convert the character sequence into a byte sequence.
* If the specified encoding is null, then ISO-8859-1 is assumed
*
* @param string the string to encode.
* @param encoding the encoding used to convert the string into the
* byte sequence to submit for MD5 digest
* @return a hexidecimal character sequence representing the MD5
* digest of the specified string
* @throws HsqlUnsupportedOperationException if an MD5 digest
* algorithm is not available through the
* java.security.MessageDigest spi or the requested
* encoding is not available
*/
public static final String encode(String string,
String encoding) throws RuntimeException {
return StringConverter.byteArrayToHexString(digest(string,
encoding));
}
/**
* Retrieves a byte sequence representing the MD5 digest of the
* specified character sequence, using the specified encoding to
* first convert the character sequence into a byte sequence.
* If the specified encoding is null, then ISO-8859-1 is
* assumed.
*
* @param string the string to digest.
* @param encoding the character encoding.
* @return the digest as an array of 16 bytes.
* @throws HsqlUnsupportedOperationException if an MD5 digest
* algorithm is not available through the
* java.security.MessageDigest spi or the requested
* encoding is not available
*/
public static byte[] digest(String string,
String encoding)
throws RuntimeException {
byte[] data;
if (encoding == null) {
encoding = "ISO-8859-1";
}
try {
data = string.getBytes(encoding);
} catch (UnsupportedEncodingException x) {
throw new RuntimeException(x.toString());
}
return digest(data);
}
/**
* Retrieves a byte sequence representing the MD5 digest of the
* specified byte sequence.
*
* @param data the data to digest.
* @return the MD5 digest as an array of 16 bytes.
* @throws HsqlUnsupportedOperationException if an MD5 digest
* algorithm is not available through the
* java.security.MessageDigest spi
*/
public static final byte[] digest(byte[] data)
throws RuntimeException {
synchronized (MD5.class) {
if (md5 == null) {
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.toString());
}
}
return md5.digest(data);
}
}
}