/* * Copyright (C) 2000 - 2008 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ */ package com.nary.security; /** * This class encrypts and decrypts Strings and uses Base64 encoding to keep them below 128 * */ import com.nary.net.Base64; public class encrypter extends Object { /* * encryptDBpassword * * In older versions of BD the DB passwords weren't encrypted. To support * backwards compatibility, we prefix a DB password with "enc-" so the decryptDBpassword * can determine if it is a new encrypted password or old unencrypted password. */ public static String encryptDBpassword( String _inString, String _key ){ if ( ( _inString == null ) || ( _inString.length() == 0 ) ) return _inString; return encrypt( "enc-" + _inString, _key ); } public static String decryptDBpassword( String _inString, String _key ){ if ( ( _inString == null ) || ( _inString.length() == 0 ) ) return _inString; try { String pwd = decrypt( _inString, _key ); if ( pwd.startsWith("enc-") ) return pwd.substring("enc-".length()); } catch ( Exception exc ) { // ignore } // Must be an old unencrypted password so just return the passed in string return _inString; } /** * encrypt * * Encrypt a string value using the given key: * * 1. generate a 32-bit int key from the key string * 2. mask (XOR) the string using the int key * 3. Base64-encode the masked string */ public static String encrypt( String _inString, String _key ){ return Base64.base64Encode( mask( _inString, generateKey( _key ) ) ); } public static byte [] encrypt( byte [] _inbytes, String _key ){ return mask( _inbytes, generateKey( _key ) ); } /** * decrypt * * Decrypt a string; must use the same key used to encrypt: * * 1. Un-Base64-encode the string * 2. generate a 32-bit int key from the key string * 3. unmask (XOR) the string using the int key */ public static String decrypt( String _inString, String _key ) throws Exception{ return mask( Base64.base64Decode( _inString ), generateKey( _key ) ); } public static byte [] decrypt( byte [] _inbytes, String _key ){ return mask( _inbytes, generateKey( _key ) ); } /** * generateKey * * Give an key string, generate a 32-bit int key by adding up the numeric * values of the bytes in the key string and using that as a seed to create * a psuedo-random int. */ private static int generateKey( String _key ) { byte[] keyBytes = _key.getBytes(); long seed = 0; for ( int i = 0; i < keyBytes.length; i++ ) { seed += keyBytes[ i ]; } return new java.util.Random( seed ).nextInt(); } /** * mask * * Mask a string using a 32-bit int mask by applying successive bytes * from the mask to the characters in the string. So character 0 of the * string gets masked by byte 0, character 1 by byte 1, etc., until * character 4 gets masekd by byte 0 again. */ private static String mask( String s, int mask ) { char[] maskBytes = new char[ 4 ]; maskBytes[ 0 ] = (char)(mask & 0x00FF); maskBytes[ 1 ] = (char)((mask >> 8) & 0x00FF); maskBytes[ 2 ] = (char)((mask >> 16) & 0x00FF); maskBytes[ 3 ] = (char)((mask >> 24) & 0x00FF); char[] c = s.toCharArray(); for ( int i = 0; i < c.length; i ++ ) { c[ i ] = (char)(c[ i ] ^ maskBytes[ i % 4 ]); } return new String( c ); } private static byte [] mask( byte [] b, int mask ) { byte[] maskBytes = new byte[ 4 ]; maskBytes[ 0 ] = (byte)(mask & 0x00FF); maskBytes[ 1 ] = (byte)((mask >> 8) & 0x00FF); maskBytes[ 2 ] = (byte)((mask >> 16) & 0x00FF); maskBytes[ 3 ] = (byte)((mask >> 24) & 0x00FF); byte [] newb = new byte[b.length]; for ( int i = 0; i < b.length; i ++ ) { newb[ i ] = (byte) ( b[ i ] ^ maskBytes[ i % 4 ] ); } return newb; } /** * encrypt-old * * Encrypt a string value using the given key: * * !* old algorithm, restored to support previous installations; * although, this is not used since only decryption is necessary. */ public static String encrypt_old( String _inString, String _key ) { char [] key = _key.toCharArray(); int k = 0; for ( int x = 0; x < key.length; x++ ){ k += key[x]; } char [] value = _inString.toCharArray(); for ( int x = 0; x < value.length; x++ ){ value[x] += k; } return com.nary.net.Base64.base64Encode( new String( value ) ); } /** * decrypt-old * * Decrypt a string; must use the same key used to encrypt: * * !* old algorithm, restored to support previous installations. */ public static String decrypt_old( String _inString, String _key ) throws Exception { String inString = ""; try{ inString = com.nary.net.Base64.base64Decode( _inString ); }catch(Exception e){ throw new Exception(); } char [] key = _key.toCharArray(); int k = 0; for ( int x = 0; x < key.length; x++ ){ k += key[x]; } char [] value = inString.toCharArray(); for ( int x = 0; x < value.length; x++ ){ value[x] -= k; } return new String( value ); } }