1 package org.apache.fulcrum.jce.crypto;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.UnsupportedEncodingException;
23 import java.security.MessageDigest;
24 import java.security.NoSuchAlgorithmException;
25
26 /**
27 * The implementation supplies a default password in the case that
28 * the programmer don't want to have additional hassles. It is easy to
29 * reengineer the password being used but much better than a hard-coded
30 * password in the application.
31 *
32 * The code uses parts from Markus Hahn's Blowfish library found at
33 * http://blowfishj.sourceforge.net/
34 *
35 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
36 * @author <a href="mailto:maakus@earthlink.net">Markus Hahn</a>
37 */
38
39 public class PasswordFactory implements PasswordParameters
40 {
41 /**
42 * @return a default password using "xxxx-xxxx-xxxx-xxxxx"
43 */
44 public static final char[] create()
45 throws NoSuchAlgorithmException, UnsupportedEncodingException
46 {
47 return create(
48 PasswordParameters.DEFAULTPASSWORD,
49 PasswordParameters.SALT,
50 PasswordParameters.COUNT
51 );
52 }
53
54 /**
55 * @param seed the default password supplied by the caller
56 * @return a password using "xxxx-xxxx-xxxx-xxxxx"
57 */
58 public static final char[] create( String seed )
59 throws NoSuchAlgorithmException, UnsupportedEncodingException
60 {
61 return create(
62 seed.toCharArray()
63 );
64 }
65
66 /**
67 * @param seed the default password supplied by the caller
68 * @return a password using "xxxx-xxxx-xxxx-xxxxx"
69 */
70 public static final char[] create( char[] seed )
71 throws NoSuchAlgorithmException, UnsupportedEncodingException
72 {
73 return create(
74 seed,
75 PasswordParameters.SALT,
76 PasswordParameters.COUNT
77 );
78 }
79
80 /**
81 * Creates a default password using "xxxx-xxxx-xxxx-xxxxx".
82 *
83 * @param salt the password salt
84 * @param password the default password
85 * @param count number of MessageDigest iterations
86 * @return the default password
87 * @throws NoSuchAlgorithmException the encryption algorithm is not supported
88 * @throws UnsupportedEncodingException the requested encoding is not supported
89 */
90 public static final char [] create( char[] password, byte[] salt, int count )
91 throws NoSuchAlgorithmException, UnsupportedEncodingException
92 {
93 char [] result = null;
94 MessageDigest sha1 = MessageDigest.getInstance( "SHA1" );
95 byte [] passwordMask = new String( password ).getBytes( "UTF-8" );
96 byte [] temp = new byte[salt.length + passwordMask.length];
97 byte [] digest = null;
98
99 StringBuffer stringBuffer = new StringBuffer();
100
101
102
103 System.arraycopy( passwordMask, 0, temp, 0, passwordMask.length );
104 System.arraycopy( salt, 0, temp, passwordMask.length, salt.length );
105
106
107
108 digest = temp;
109
110 for (int i = 0; i < count; i++)
111 {
112 sha1.update( digest );
113 digest = sha1.digest();
114 }
115
116
117
118
119 long long1 = createLong( digest, 0 );
120 long long2 = createLong( digest, 4 );
121 long long3 = createLong( digest, 8 );
122 long long4 = createLong( digest, 12 );
123
124 stringBuffer.append( Long.toHexString( long1 ).substring( 0, 4 ) );
125 stringBuffer.append( '-' );
126 stringBuffer.append( Long.toHexString( long2 ).substring( 0, 4 ) );
127 stringBuffer.append( '-' );
128 stringBuffer.append( Long.toHexString( long3 ).substring( 0, 4 ) );
129 stringBuffer.append( '-' );
130 stringBuffer.append( Long.toHexString( long4 ).substring( 0, 5 ) );
131
132
133
134 result = new char[stringBuffer.length()];
135
136 for (int i = 0; i < stringBuffer.length(); i++)
137 {
138 result[i] = stringBuffer.charAt( i );
139 }
140
141
142
143 for (int i = 0; i < stringBuffer.length(); i++)
144 {
145 stringBuffer.setCharAt( i, ' ' );
146 }
147
148 return result;
149 }
150
151 /**
152 * Gets bytes from an array into a long.
153 *
154 * @param buf where to get the bytes
155 * @param nOfs index from where to read the data
156 * @return the 64bit integer
157 */
158 private static final long createLong(byte [] buf, int nOfs)
159 {
160 return
161 ((long)(( buf[nOfs ] << 24) |
162 ((buf[nOfs + 1] & 0x0ff) << 16) |
163 ((buf[nOfs + 2] & 0x0ff) << 8) |
164 ( buf[nOfs + 3] & 0x0ff )) << 32) |
165 ((long)(( buf[nOfs + 4] << 24) |
166 ((buf[nOfs + 5] & 0x0ff) << 16) |
167 ((buf[nOfs + 6] & 0x0ff) << 8) |
168 ( buf[nOfs + 7] & 0x0ff )) & 0x0ffffffffL);
169 }
170 }