KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > util > PasswordUtils


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: PasswordUtils.java,v 1.7 2007/01/07 06:14:01 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.util;
23
24 import java.security.MessageDigest JavaDoc;
25 import java.security.NoSuchAlgorithmException JavaDoc;
26 import java.security.NoSuchProviderException JavaDoc;
27 import java.security.Security JavaDoc;
28 import java.util.Properties JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30
31 import org.bouncycastle.jce.provider.BouncyCastleProvider;
32 import org.opensubsystems.core.error.OSSException;
33 import org.opensubsystems.core.error.OSSInternalErrorException;
34
35 /**
36  * Class responsible for encrypting of data.
37  *
38  * @version $Id: PasswordUtils.java,v 1.7 2007/01/07 06:14:01 bastafidli Exp $
39  * @author Julo Legeny
40  * @code.reviewer Miro Halas
41  * @code.reviewed 1.4 2005/07/29 07:36:24 bastafidli
42  */

43 public final class PasswordUtils
44 {
45    // Configuration constants //////////////////////////////////////////////////
46

47    /**
48     * Configuration setting allowing to specify algorithm to generate message
49     * digests for verifying passwords.
50     * The standard names of the algorithms are defined by
51     * Java Cryptography Architecture API Specification Reference
52     * http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA
53     */

54    public static final String JavaDoc PASSWORD_DIGEST_ALGORITHM = "oss.messagedigest.algorithm";
55    
56    /**
57     * Configuration setting allowing to specify algorithm implementation provider
58     * to use for an algorithm defined by property oss.messagedigest.algorithm.
59     */

60    public static final String JavaDoc PASSWORD_ALGORITHM_PROVIDER = "oss.messagedigest.provider";
61    
62    // Constants ////////////////////////////////////////////////////////////////
63

64    /**
65     * Default algorithm to use to encrpt passwords. Get a message digest object
66     * using the SHA1 algorithm (since MD5 showed recently vulnerability).
67     */

68    public static final String JavaDoc PASSWORD_DIGEST_ALGORITHM_DEFAULT = "SHA-1";
69    
70    /**
71     * Default provider algorithm of which to use. By default we use Bouncy Castle
72     * algoritm implementations.
73     */

74    public static final String JavaDoc PASSWORD_ALGORITHM_PROVIDER_DEFAULT = "BC";
75    
76    // Cached variables /////////////////////////////////////////////////////////
77

78    /**
79     * Logger for this class
80     */

81    private static Logger JavaDoc s_logger = Log.getInstance(PasswordUtils.class);
82
83    /**
84     * Algorithm used to encrypt password. The standard names of the algorithms
85     * are defined by Java Cryptography Architecture API Specification Reference
86     * http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA
87     */

88    protected static String JavaDoc s_strPasswordAlgorithm;
89    
90    /**
91     * Provider lgorithm of which to use.
92     */

93    protected static String JavaDoc s_strPasswordAlgorithmProvider;
94    
95    // Constructors /////////////////////////////////////////////////////////////
96

97    /**
98     * Static initializer
99     */

100    static
101    {
102       // Install the Bouncy Castle provider so that we have at least the default
103
// provider always available
104
Security.addProvider(new BouncyCastleProvider());
105
106       // Read configuration parameters
107
Properties JavaDoc prpSettings;
108       String JavaDoc strParam;
109       
110       prpSettings = Config.getInstance().getPropertiesSafely();
111
112       // Do not use here the predefined methods on Config object and instead
113
// read the parameters directly since we want to perform special validation
114
strParam = prpSettings.getProperty(PASSWORD_DIGEST_ALGORITHM,
115                                          PASSWORD_DIGEST_ALGORITHM);
116       if ((strParam.length() == 0) || (strParam.equals(PASSWORD_DIGEST_ALGORITHM)))
117       {
118          s_logger.config("Password digest algorithm is not set in property "
119                          + PASSWORD_DIGEST_ALGORITHM + ", using default value "
120                          + PASSWORD_DIGEST_ALGORITHM_DEFAULT);
121          s_strPasswordAlgorithm = PASSWORD_DIGEST_ALGORITHM_DEFAULT;
122       }
123       strParam = prpSettings.getProperty(PASSWORD_ALGORITHM_PROVIDER,
124                                          PASSWORD_ALGORITHM_PROVIDER);
125       // Empty string is valid value for a provider
126
if ((strParam.equals(PASSWORD_ALGORITHM_PROVIDER)))
127       {
128          s_logger.config("Password digest algorithm provider is not set in property "
129                          + PASSWORD_ALGORITHM_PROVIDER + ", using default value "
130                          + PASSWORD_ALGORITHM_PROVIDER_DEFAULT);
131          s_strPasswordAlgorithmProvider = PASSWORD_ALGORITHM_PROVIDER_DEFAULT;
132       }
133       
134       // Now try to construct that algorithm
135
try
136       {
137          if ((s_strPasswordAlgorithmProvider != null)
138             && (s_strPasswordAlgorithmProvider.length() > 0))
139          {
140             MessageDigest.getInstance(s_strPasswordAlgorithm,
141                                       s_strPasswordAlgorithmProvider);
142          }
143          else
144          {
145             MessageDigest.getInstance(s_strPasswordAlgorithm);
146          }
147       }
148       catch (NoSuchAlgorithmException JavaDoc algExc)
149       {
150          assert (!PASSWORD_DIGEST_ALGORITHM_DEFAULT.equals(s_strPasswordAlgorithm))
151                 || (!PASSWORD_ALGORITHM_PROVIDER_DEFAULT.equals(s_strPasswordAlgorithmProvider))
152                 : "Default algorithm provided by default provider has to be always found.";
153
154          s_logger.config("Algorithm " + s_strPasswordAlgorithm + " set in property "
155                         + PASSWORD_DIGEST_ALGORITHM + " provided by provider "
156                         + s_strPasswordAlgorithmProvider + " set in property "
157                         + PASSWORD_ALGORITHM_PROVIDER + " doesn't exist, using"
158                         + " default values " + PASSWORD_DIGEST_ALGORITHM_DEFAULT
159                         + " and " + PASSWORD_ALGORITHM_PROVIDER_DEFAULT);
160          s_strPasswordAlgorithm = PASSWORD_DIGEST_ALGORITHM_DEFAULT;
161          s_strPasswordAlgorithmProvider = PASSWORD_ALGORITHM_PROVIDER_DEFAULT;
162       }
163       catch (NoSuchProviderException JavaDoc provExc)
164       {
165          assert (!PASSWORD_DIGEST_ALGORITHM_DEFAULT.equals(s_strPasswordAlgorithm))
166                 || (!PASSWORD_ALGORITHM_PROVIDER_DEFAULT.equals(s_strPasswordAlgorithmProvider))
167                 : "Default algorithm provided by default provider has to be always found.";
168
169          s_logger.config("Algorithm " + s_strPasswordAlgorithm + " set in property "
170                         + PASSWORD_DIGEST_ALGORITHM + " provided by provider "
171                         + s_strPasswordAlgorithmProvider + " set in property "
172                         + PASSWORD_ALGORITHM_PROVIDER + " doesn't exist, using"
173                         + " default values " + PASSWORD_DIGEST_ALGORITHM_DEFAULT
174                         + " and " + PASSWORD_ALGORITHM_PROVIDER_DEFAULT);
175          s_strPasswordAlgorithm = PASSWORD_DIGEST_ALGORITHM_DEFAULT;
176          s_strPasswordAlgorithmProvider = PASSWORD_ALGORITHM_PROVIDER_DEFAULT;
177       }
178       s_logger.config(PASSWORD_DIGEST_ALGORITHM + " = " + s_strPasswordAlgorithm);
179       s_logger.config(PASSWORD_ALGORITHM_PROVIDER + " = " + s_strPasswordAlgorithmProvider);
180    }
181    
182    /**
183     * Private constructor since this class cannot be instantiated
184     */

185    private PasswordUtils(
186    )
187    {
188       // Do nothing
189
}
190    
191    // Public methods ///////////////////////////////////////////////////////////
192

193    /**
194     * Generate message digest from specified data.
195     *
196     * @param strData - data to generate digest from
197     * @return String - generate message digest
198     * @throws OSSException - an error has occured
199     */

200    public static String JavaDoc getMessageDigest(
201       String JavaDoc strData
202    ) throws OSSException
203    {
204       byte[] plainText;
205       MessageDigest JavaDoc messageDigest;
206
207       try
208       {
209          if ((s_strPasswordAlgorithmProvider != null)
210             && (s_strPasswordAlgorithmProvider.length() > 0))
211          {
212             messageDigest = MessageDigest.getInstance(s_strPasswordAlgorithm,
213                                                       s_strPasswordAlgorithmProvider);
214          }
215          else
216          {
217             messageDigest = MessageDigest.getInstance(s_strPasswordAlgorithm);
218          }
219       }
220       catch (NoSuchAlgorithmException JavaDoc algExc)
221       {
222          throw new OSSInternalErrorException(
223             "Cannot construct algorithm already verified in static constructor.",
224             algExc);
225       }
226       catch (NoSuchProviderException JavaDoc provExc)
227       {
228          throw new OSSInternalErrorException(
229             "Cannot construct algorithm already verified in static constructor.",
230             provExc);
231       }
232       
233       // Calculate the digest
234
plainText = strData.getBytes();
235       messageDigest.update(plainText);
236
237       // Get the data hash
238
byte[] arrBytes = messageDigest.digest();
239       StringBuffer JavaDoc strFinal = new StringBuffer JavaDoc();
240       for (int iCount = 0; iCount < arrBytes.length; iCount++)
241       {
242          // By converting it into the hexa-decimal number format it is
243
// guaranteed, that the final string will have maximal length
244
// 2 * length (e.g. 32 chars (16 chars is the output from SHA1 and each
245
// sign from the SHA1 string can be converted at most to the
246
// 2 chars - hexa-decimal number (from 0 to 255)))
247
strFinal.append(Integer.toHexString(
248             (int) arrBytes[iCount] + (int) (-1 * Byte.MIN_VALUE)));
249       }
250       return strFinal.toString();
251    }
252 }
253
Popular Tags