KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > security > auth > module > Crypt


1 /*
2  * @(#)Crypt.java 1.7 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /* Copyright (c) 1988 AT&T */
9 /* All Rights Reserved */
10
11 /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
12 /* The copyright notice above does not evidence any */
13 /* actual or intended publication of such source code. */
14
15
16 /**
17  * Implements the UNIX crypt(3) function, based on a direct port of the
18  * libc crypt function.
19  *
20  * <p>
21  * From the crypt man page:
22  * <p>
23  * crypt() is the password encryption routine, based on the NBS
24  * Data Encryption Standard, with variations intended (among
25  * other things) to frustrate use of hardware implementations
26  * of the DES for key search.
27  * <p>
28  * The first argument to crypt() is normally a user's typed
29  * password. The second is a 2-character string chosen from
30  * the set [a-zA-Z0-9./]. the salt string is used to perturb
31  * the DES algorithm in one
32  * of 4096 different ways, after which the password is used as
33  * the key to encrypt repeatedly a constant string. The
34  * returned value points to the encrypted password, in the same
35  * alphabet as the salt. The first two characters are the salt
36  * itself.
37  *
38  * @version 1.5, 01/11/00
39  * @author Roland Schemers
40  */

41
42 package com.sun.security.auth.module;
43
44 class Crypt {
45
46 /* EXPORT DELETE START */
47
48     private static final byte[] IP = {
49     58, 50, 42, 34, 26, 18, 10, 2,
50     60, 52, 44, 36, 28, 20, 12, 4,
51     62, 54, 46, 38, 30, 22, 14, 6,
52     64, 56, 48, 40, 32, 24, 16, 8,
53     57, 49, 41, 33, 25, 17, 9, 1,
54     59, 51, 43, 35, 27, 19, 11, 3,
55     61, 53, 45, 37, 29, 21, 13, 5,
56     63, 55, 47, 39, 31, 23, 15, 7,
57     };
58
59     private static final byte[] FP = {
60     40, 8, 48, 16, 56, 24, 64, 32,
61     39, 7, 47, 15, 55, 23, 63, 31,
62     38, 6, 46, 14, 54, 22, 62, 30,
63     37, 5, 45, 13, 53, 21, 61, 29,
64     36, 4, 44, 12, 52, 20, 60, 28,
65     35, 3, 43, 11, 51, 19, 59, 27,
66     34, 2, 42, 10, 50, 18, 58, 26,
67     33, 1, 41, 9, 49, 17, 57, 25,
68     };
69
70     private static final byte[] PC1_C = {
71     57, 49, 41, 33, 25, 17, 9,
72     1, 58, 50, 42, 34, 26, 18,
73     10, 2, 59, 51, 43, 35, 27,
74     19, 11, 3, 60, 52, 44, 36,
75     };
76
77     private static final byte[] PC1_D = {
78     63, 55, 47, 39, 31, 23, 15,
79     7, 62, 54, 46, 38, 30, 22,
80     14, 6, 61, 53, 45, 37, 29,
81     21, 13, 5, 28, 20, 12, 4,
82     };
83
84     private static final byte[] shifts = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, };
85
86     private static final byte[] PC2_C = {
87     14, 17, 11, 24, 1, 5,
88     3, 28, 15, 6, 21, 10,
89     23, 19, 12, 4, 26, 8,
90     16, 7, 27, 20, 13, 2,
91     };
92
93     private static final byte[] PC2_D = {
94     41,52,31,37,47,55,
95     30,40,51,45,33,48,
96     44,49,39,56,34,53,
97     46,42,50,36,29,32,
98     };
99
100     private byte[] C = new byte[28];
101     private byte[] D = new byte[28];
102
103     private byte[] KS;
104
105     private byte[] E = new byte[48];
106
107     private static final byte[] e2 = {
108     32, 1, 2, 3, 4, 5,
109     4, 5, 6, 7, 8, 9,
110     8, 9,10,11,12,13,
111     12,13,14,15,16,17,
112     16,17,18,19,20,21,
113     20,21,22,23,24,25,
114     24,25,26,27,28,29,
115     28,29,30,31,32, 1,
116     };
117
118     private void setkey(byte[] key) {
119     int i, j, k;
120     byte t;
121
122     if (KS == null) {
123         KS = new byte[16*48];
124     }
125
126     for (i = 0; i < 28; i++) {
127         C[i] = key[PC1_C[i]-1];
128         D[i] = key[PC1_D[i]-1];
129     }
130     for (i = 0; i < 16; i++) {
131         for (k = 0; k < shifts[i]; k++) {
132             t = C[0];
133             for (j = 0; j < 28-1; j++)
134                 C[j] = C[j+1];
135             C[27] = t;
136             t = D[0];
137             for (j = 0; j < 28-1; j++)
138                 D[j] = D[j+1];
139             D[27] = t;
140         }
141         for (j = 0; j < 24; j++) {
142             int index = i * 48;
143
144             KS[index+j] = C[PC2_C[j]-1];
145             KS[index+j+24] = D[PC2_D[j]-28-1];
146         }
147     }
148     for (i = 0; i < 48; i++)
149         E[i] = e2[i];
150     }
151
152
153     private static final byte[][] S = {
154     {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
155     0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
156     4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
157     15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
158
159     {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
160     3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
161     0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
162     13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
163
164     {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
165     13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
166     13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
167      1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
168
169     {7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
170     13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
171     10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
172      3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
173
174     {2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
175     14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
176      4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
177     11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
178
179     {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
180     10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
181      9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
182      4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
183
184     {4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
185     13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
186      1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
187      6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
188
189     {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
190      1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
191      7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
192      2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
193     };
194
195
196     private static final byte[] P = {
197     16, 7,20,21,
198     29,12,28,17,
199      1,15,23,26,
200      5,18,31,10,
201      2, 8,24,14,
202     32,27, 3, 9,
203     19,13,30, 6,
204     22,11, 4,25,
205     };
206
207     private byte[] L = new byte[64];
208     private byte[] tempL = new byte[32];
209     private byte[] f = new byte[32];
210     private byte[] preS = new byte[48];
211
212
213     private void encrypt(byte[] block,int fake) {
214     int i;
215     int t, j, k;
216     int R = 32; // &L[32]
217

218     if (KS == null) {
219         KS = new byte[16*48];
220     }
221
222     for(j=0; j < 64; j++) {
223         L[j] = block[IP[j]-1];
224     }
225     for(i=0; i < 16; i++) {
226         int index = i * 48;
227
228         for(j=0; j < 32; j++) {
229         tempL[j] = L[R+j];
230         }
231         for(j=0; j < 48; j++) {
232         preS[j] = (byte) (L[R+E[j]-1] ^ KS[index+j]);
233         }
234         for(j=0; j < 8; j++) {
235         t = 6*j;
236         k = S[j][(preS[t+0]<<5)+
237              (preS[t+1]<<3)+
238              (preS[t+2]<<2)+
239              (preS[t+3]<<1)+
240              (preS[t+4]<<0)+
241              (preS[t+5]<<4)];
242         t = 4*j;
243         f[t+0] = (byte) ((k>>3)&01);
244         f[t+1] = (byte) ((k>>2)&01);
245         f[t+2] = (byte) ((k>>1)&01);
246         f[t+3] = (byte) ((k>>0)&01);
247         }
248         for(j=0; j < 32; j++) {
249             L[R+j] = (byte) (L[j] ^ f[P[j]-1]);
250         }
251         for(j=0; j < 32; j++) {
252             L[j] = tempL[j];
253         }
254     }
255     for(j=0; j < 32; j++) {
256         t = L[j];
257         L[j] = L[R+j];
258         L[R+j] = (byte)t;
259     }
260     for(j=0; j < 64; j++) {
261         block[j] = L[FP[j]-1];
262     }
263     }
264 /* EXPORT DELETE END */
265
266     /**
267      * Creates a new Crypt object for use with the crypt method.
268      *
269      */

270
271     public Crypt()
272     {
273     // does nothing at this time
274
super();
275     }
276
277     /**
278      * Implements the libc crypt(3) function.
279      *
280      * @param pw the password to "encrypt".
281      *
282      * @param salt the salt to use.
283      *
284      * @return A new byte[13] array that contains the encrypted
285      * password. The first two characters are the salt.
286      *
287      */

288
289     public synchronized byte[] crypt(byte[] pw, byte[] salt) {
290     int c, i, j, pwi;
291     byte temp;
292     byte[] block = new byte[66];
293     byte[] iobuf = new byte[13];
294
295 /* EXPORT DELETE START */
296
297     pwi = 0;
298
299     for(i=0; pwi < pw.length && i < 64; pwi++) {
300         c = pw[pwi];
301         for(j=0; j < 7; j++, i++) {
302         block[i] = (byte) ((c>>(6-j)) & 01);
303         }
304         i++;
305     }
306
307     setkey(block);
308
309     for(i=0; i < 66; i++) {
310         block[i] = 0;
311     }
312
313     for(i=0; i < 2; i++) {
314         c = salt[i];
315         iobuf[i] = (byte)c;
316         if(c > 'Z')
317         c -= 6;
318         if(c > '9')
319         c -= 7;
320         c -= '.';
321         for(j=0; j < 6; j++) {
322         if( ((c>>j) & 01) != 0) {
323             temp = E[6*i+j];
324             E[6*i+j] = E[6*i+j+24];
325             E[6*i+j+24] = temp;
326         }
327         }
328     }
329
330     for(i=0; i < 25; i++) {
331         encrypt(block,0);
332     }
333
334     for(i=0; i < 11; i++) {
335         c = 0;
336         for(j=0; j < 6; j++) {
337         c <<= 1;
338         c |= block[6*i+j];
339         }
340         c += '.';
341         if(c > '9') {
342         c += 7;
343         }
344         if(c > 'Z') {
345         c += 6;
346         }
347         iobuf[i+2] = (byte)c;
348     }
349     //iobuf[i+2] = 0;
350
if(iobuf[1] == 0) {
351         iobuf[1] = iobuf[0];
352     }
353 /* EXPORT DELETE END */
354     return(iobuf);
355     }
356
357     /**
358      * program to test the crypt routine.
359      *
360      * The first parameter is the cleartext password, the second is
361      * the salt to use. The salt should be two characters from the
362      * set [a-zA-Z0-9./]. Outputs the crypt result.
363      *
364      * @param arg command line arguments.
365      *
366      */

367       
368     public static void main(String JavaDoc arg[]) {
369
370     if (arg.length!=2) {
371         System.err.println("usage: Crypt password salt");
372         System.exit(1);
373     }
374
375     Crypt c = new Crypt();
376     try {
377         byte result[] = c.crypt
378             (arg[0].getBytes("ISO-8859-1"), arg[1].getBytes("ISO-8859-1"));
379         for (int i=0; i<result.length; i++) {
380             System.out.println(" "+i+" "+(char)result[i]);
381         }
382     } catch (java.io.UnsupportedEncodingException JavaDoc uee) {
383         // cannot happen
384
}
385     }
386 }
387
Popular Tags