001    /*
002     * @(#)UnixCrypt.java   0.9 96/11/25
003     *
004     * Copyright (c) 1996 Aki Yoshida. All rights reserved.
005     *
006     * Permission to use, copy, modify and distribute this software
007     * for non-commercial or commercial purposes and without fee is
008     * hereby granted provided that this copyright notice appears in
009     * all copies.
010     */
011    
012    package com.hs.mail.security.login;
013    
014    /**
015     * Unix crypt(3C) utility
016     *
017     * @version 0.9, 11/25/96
018     * @author      Aki Yoshida
019     */
020    public class CryptPasswordEncoder implements PasswordEncoder {
021    
022            /**
023             * (mostly) Standard DES Tables from Tom Truscott
024             */
025        private static final byte[] IP = { /* initial permutation */
026            58, 50, 42, 34, 26, 18, 10,  2,
027            60, 52, 44, 36, 28, 20, 12,  4,
028            62, 54, 46, 38, 30, 22, 14,  6,
029            64, 56, 48, 40, 32, 24, 16,  8,
030            57, 49, 41, 33, 25, 17,  9,  1,
031            59, 51, 43, 35, 27, 19, 11,  3,
032            61, 53, 45, 37, 29, 21, 13,  5,
033            63, 55, 47, 39, 31, 23, 15,  7
034        };
035    
036        /**
037         * The final permutation is the inverse of IP - no table is necessary
038         */
039        private static final byte[] ExpandTr = { /* expansion operation */
040            32,  1,  2,  3,  4,  5,
041             4,  5,  6,  7,  8,  9,
042             8,  9, 10, 11, 12, 13,
043            12, 13, 14, 15, 16, 17,
044            16, 17, 18, 19, 20, 21,
045            20, 21, 22, 23, 24, 25,
046            24, 25, 26, 27, 28, 29,
047            28, 29, 30, 31, 32,  1 
048        };
049    
050        private static final byte[] PC1 = { /* permuted choice table 1 */
051            57, 49, 41, 33, 25, 17,  9,
052             1, 58, 50, 42, 34, 26, 18,
053            10,  2, 59, 51, 43, 35, 27,
054            19, 11,  3, 60, 52, 44, 36,
055        
056            63, 55, 47, 39, 31, 23, 15,
057             7, 62, 54, 46, 38, 30, 22,
058            14,  6, 61, 53, 45, 37, 29,
059            21, 13,  5, 28, 20, 12,  4
060            };
061    
062        private static final byte[] Rotates = {     /* PC1 rotation schedule */
063            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
064            };
065    
066        private static final byte[] PC2 = { /* permuted choice table 2 */
067             9, 18,    14, 17, 11, 24,  1,  5,
068            22, 25,     3, 28, 15,  6, 21, 10,
069            35, 38,    23, 19, 12,  4, 26,  8,
070            43, 54,    16,  7, 27, 20, 13,  2,
071    
072             0,  0,    41, 52, 31, 37, 47, 55,
073             0,  0,    30, 40, 51, 45, 33, 48,
074             0,  0,    44, 49, 39, 56, 34, 53,
075             0,  0,    46, 42, 50, 36, 29, 32
076            };
077    
078        private static final byte[][] S = { /* 48->32 bit substitution tables */
079            /* S[1] */
080            {14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
081              0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
082              4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
083             15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13},
084            /* S[2] */
085            {15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
086              3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
087              0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
088             13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9},
089            /* S[3] */
090            {10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
091             13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
092             13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
093              1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12},
094            /* S[4] */
095            { 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
096             13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
097             10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
098              3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14},
099            /* S[5] */
100            { 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
101             14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
102              4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
103             11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3},
104            /* S[6] */
105            {12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
106             10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
107              9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
108              4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13},
109            /* S[7] */
110            { 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
111             13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
112              1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
113              6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12},
114            /* S[8] */
115            {13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
116              1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
117              7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
118              2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}
119            };
120    
121        private static final byte[] P32Tr = { /* 32-bit permutation function */
122            16,  7, 20, 21,
123            29, 12, 28, 17,
124             1, 15, 23, 26,
125             5, 18, 31, 10,
126             2,  8, 24, 14,
127            32, 27,  3,  9,
128            19, 13, 30,  6,
129            22, 11,  4, 25
130            };
131    
132        private static final byte[] CIFP = { /* compressed/interleaved permutation */
133             1,  2,  3,  4,   17, 18, 19, 20,
134             5,  6,  7,  8,   21, 22, 23, 24,
135             9, 10, 11, 12,   25, 26, 27, 28,
136            13, 14, 15, 16,   29, 30, 31, 32,
137    
138            33, 34, 35, 36,   49, 50, 51, 52,
139            37, 38, 39, 40,   53, 54, 55, 56,
140            41, 42, 43, 44,   57, 58, 59, 60,
141            45, 46, 47, 48,   61, 62, 63, 64
142            };
143    
144        private static final byte[] ITOA64 = { /* 0..63 => ascii-64 */
145            (byte)'.',(byte) '/',(byte) '0',(byte) '1',(byte) '2',(byte) '3',(byte) '4',(byte) '5',
146            (byte)'6',(byte) '7',(byte) '8',(byte) '9',(byte) 'A',(byte) 'B',(byte) 'C',(byte) 'D',
147            (byte)'E',(byte) 'F',(byte) 'G',(byte) 'H',(byte) 'I',(byte) 'J',(byte) 'K',(byte) 'L', 
148            (byte)'M',(byte) 'N',(byte) 'O',(byte) 'P',(byte) 'Q',(byte) 'R',(byte) 'S',(byte) 'T', 
149            (byte)'U',(byte) 'V',(byte) 'W',(byte) 'X',(byte) 'Y',(byte) 'Z',(byte) 'a',(byte) 'b', 
150            (byte)'c',(byte) 'd',(byte) 'e',(byte) 'f',(byte) 'g',(byte) 'h',(byte) 'i',(byte) 'j', 
151            (byte)'k',(byte) 'l',(byte) 'm',(byte) 'n',(byte) 'o',(byte) 'p',(byte) 'q',(byte) 'r', 
152            (byte)'s',(byte) 't',(byte) 'u',(byte) 'v',(byte) 'w',(byte) 'x',(byte) 'y',(byte) 'z'
153            };
154    
155        /* =====  Tables that are initialized at run time  ==================== */
156    
157        /**
158         * ascii-64 => 0..63
159         */
160            private static byte[] A64TOI = new byte[128];
161    
162            /**
163             * Initial key schedule permutation 
164             */
165            private static long[][] PC1ROT = new long[16][16];
166    
167            /**
168             * Subsequent key schedule rotation permutations
169             */
170            private static long[][][] PC2ROT = new long[2][16][16];
171    
172            /**
173             * Initial permutation/expansion table
174             */
175            private static long[][] IE3264 = new long[8][16];
176    
177            /** 
178             * Table that combines the S, P, and E operations.
179             */
180            private static long[][] SPE = new long[8][64];
181    
182            /**
183             * compressed/interleaved => final permutation table
184             */
185            private static long[][] CF6464 = new long[16][16];
186    
187            static {
188            byte[] perm = new byte[64];
189            byte[] temp = new byte[64];
190    
191            // inverse table.
192            for (int i=0; i<64; i++) A64TOI[ITOA64[i]] = (byte)i;
193    
194            // PC1ROT - bit reverse, then PC1, then Rotate, then PC2
195            for (int i=0; i<64; i++) perm[i] = (byte)0;;
196            for (int i=0; i<64; i++) {
197                int k;
198                if ((k = (int)PC2[i]) == 0) continue;
199                k += Rotates[0]-1;
200                if ((k%28) < Rotates[0]) k -= 28;
201                k = (int)PC1[k];
202                if (k > 0) {
203                    k--;
204                    k = (k|0x07) - (k&0x07);
205                    k++;
206                }
207                perm[i] = (byte)k;
208            }
209            init_perm(PC1ROT, perm, 8, 8);
210    
211            // PC2ROT - PC2 inverse, then Rotate, then PC2
212            for (int j=0; j<2; j++) {
213                int k;
214                for (int i=0; i<64; i++) perm[i] = temp[i] = 0;
215                for (int i=0; i<64; i++) {
216                    if ((k = (int)PC2[i]) == 0) continue;
217                    temp[k-1] = (byte)(i+1);
218                }
219                for (int i=0; i<64; i++) {
220                    if ((k = (int)PC2[i]) == 0) continue;
221                    k += j;
222                    if ((k%28) <= j) k -= 28;
223                    perm[i] = temp[k];
224                }
225    
226                init_perm(PC2ROT[j], perm, 8, 8);
227            }
228    
229            // Bit reverse, intial permupation, expantion
230            for (int i=0; i<8; i++) {
231                for (int j=0; j<8; j++) {
232                    int k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
233                    if (k > 32) k -= 32;
234                    else if (k > 0) k--;
235                    if (k > 0) {
236                        k--;
237                        k = (k|0x07) - (k&0x07);
238                        k++;
239                    }
240                    perm[i*8+j] = (byte)k;
241                }
242            }
243    
244            init_perm(IE3264, perm, 4, 8);
245    
246            // Compression, final permutation, bit reverse
247            for (int i=0; i<64; i++) {
248                int k = IP[CIFP[i]-1];
249                if (k > 0) {
250                    k--;
251                    k = (k|0x07) - (k&0x07);
252                    k++;
253                }
254                perm[k-1] = (byte)(i+1);
255            }
256    
257            init_perm(CF6464, perm, 8, 8);
258    
259            // SPE table
260            for (int i=0; i<48; i++)
261                perm[i] = P32Tr[ExpandTr[i]-1];
262            for (int t=0; t<8; t++) {
263                for (int j=0; j<64; j++) {
264                    int k = (((j >> 0) & 0x01) << 5) | (((j >> 1) & 0x01) << 3) |
265                        (((j >> 2) & 0x01) << 2) | (((j >> 3) & 0x01) << 1) |
266                        (((j >> 4) & 0x01) << 0) | (((j >> 5) & 0x01) << 4);
267                    k = S[t][k];
268                    k = (((k >> 3) & 0x01) << 0) | (((k >> 2) & 0x01) << 1) |
269                        (((k >> 1) & 0x01) << 2) | (((k >> 0) & 0x01) << 3);
270                    for (int i=0; i<32; i++) temp[i] = 0;
271                    for (int i=0; i<4; i++) temp[4*t+i] = (byte)((k >> i) & 0x01);
272                    long kk = 0;
273                    for (int i=24; --i>=0; ) kk = ((kk<<1) |
274                                                   ((long)temp[perm[i]-1])<<32 |
275                                                   ((long)temp[perm[i+24]-1]));
276    
277                    SPE[t][j] = to_six_bit(kk);
278                }
279            }
280        }
281    
282            /**
283         * Returns the transposed and split code of a 24-bit code
284         * into a 4-byte code, each having 6 bits.
285         */
286        private static int to_six_bit(int num) {
287            return (((num << 26) & 0xfc000000) | ((num << 12) & 0xfc0000) | 
288                    ((num >> 2) & 0xfc00) | ((num >> 16) & 0xfc));
289        }
290    
291        /**
292         * Returns the transposed and split code of two 24-bit code 
293         * into two 4-byte code, each having 6 bits.
294         */
295        private static long to_six_bit(long num) {
296            return (((num << 26) & 0xfc000000fc000000L) | ((num << 12) & 0xfc000000fc0000L) | 
297                    ((num >> 2) & 0xfc000000fc00L) | ((num >> 16) & 0xfc000000fcL));
298        }
299      
300        /**
301         * Returns the permutation of the given 64-bit code with
302         * the specified permutataion table.
303         */
304        private static long perm6464(long c, long[][]p) {
305            long out = 0L;
306            for (int i=8; --i>=0; ) {
307                int t = (int)(0x00ff & c);
308                c >>= 8;
309                long tp = p[i<<1][t&0x0f];
310                out |= tp;
311                tp = p[(i<<1)+1][t>>4];
312                out |= tp;
313            }
314            return out;
315        }
316    
317        /**
318         * Returns the permutation of the given 32-bit code with
319         * the specified permutataion table.
320         */
321        private static long perm3264(int c, long[][]p) {
322            long out = 0L;
323            for (int i=4; --i>=0; ) {
324                int t = (int)(0x00ff & c);
325                c >>= 8;
326                long tp = p[i<<1][t&0x0f];
327                out |= tp;
328                tp = p[(i<<1)+1][t>>4];
329                out |= tp;
330            }
331            return out;
332        }
333    
334        /**
335         * Returns the key schedule for the given key.
336         */
337        private static long[] des_setkey(long keyword) {
338            long K = perm6464(keyword, PC1ROT);
339            long[] KS = new long[16];
340            KS[0] = K&~0x0303030300000000L;
341        
342            for (int i=1; i<16; i++) {
343                KS[i] = K;
344                K = perm6464(K, PC2ROT[Rotates[i]-1]);
345    
346                KS[i] = K&~0x0303030300000000L;
347            }
348            return KS;
349        }
350    
351        /**
352         * Returns the DES encrypted code of the given word with the specified 
353         * environment.
354         */
355        private static long des_cipher(long in, int salt, int num_iter, long[] KS) {
356            salt = to_six_bit(salt);
357            long L = in;
358            long R = L;
359            L &= 0x5555555555555555L;
360            R = (R & 0xaaaaaaaa00000000L) | ((R >> 1) & 0x0000000055555555L);
361            L = ((((L << 1) | (L << 32)) & 0xffffffff00000000L) | 
362                 ((R | (R >> 32)) & 0x00000000ffffffffL));
363        
364            L = perm3264((int)(L>>32), IE3264);
365            R = perm3264((int)(L&0xffffffff), IE3264);
366    
367            while (--num_iter >= 0) {
368                for (int loop_count=0; loop_count<8; loop_count++) {
369                    long kp;
370                    long B;
371                    long k;
372    
373                    kp = KS[(loop_count<<1)];
374                    k = ((R>>32) ^ R) & salt & 0xffffffffL;
375                    k |= (k<<32);
376                    B = (k ^ R ^ kp);
377    
378                    L ^= (SPE[0][(int)((B>>58)&0x3f)] ^ SPE[1][(int)((B>>50)&0x3f)] ^
379                          SPE[2][(int)((B>>42)&0x3f)] ^ SPE[3][(int)((B>>34)&0x3f)] ^
380                          SPE[4][(int)((B>>26)&0x3f)] ^ SPE[5][(int)((B>>18)&0x3f)] ^
381                          SPE[6][(int)((B>>10)&0x3f)] ^ SPE[7][(int)((B>>2)&0x3f)]);
382    
383                    kp = KS[(loop_count<<1)+1];
384                    k = ((L>>32) ^ L) & salt & 0xffffffffL;
385                    k |= (k<<32);
386                    B = (k ^ L ^ kp);
387    
388                    R ^= (SPE[0][(int)((B>>58)&0x3f)] ^ SPE[1][(int)((B>>50)&0x3f)] ^
389                          SPE[2][(int)((B>>42)&0x3f)] ^ SPE[3][(int)((B>>34)&0x3f)] ^
390                          SPE[4][(int)((B>>26)&0x3f)] ^ SPE[5][(int)((B>>18)&0x3f)] ^
391                          SPE[6][(int)((B>>10)&0x3f)] ^ SPE[7][(int)((B>>2)&0x3f)]);
392                }
393                // swap L and R
394                L ^= R;
395                R ^= L;
396                L ^= R;
397            }
398            L = ((((L>>35) & 0x0f0f0f0fL) | (((L&0xffffffff)<<1) & 0xf0f0f0f0L))<<32 |
399                 (((R>>35) & 0x0f0f0f0fL) | (((R&0xffffffff)<<1) & 0xf0f0f0f0L)));
400    
401            L = perm6464(L, CF6464);
402    
403            return L;
404        }
405    
406        /**
407         * Initializes the given permutation table with the mapping table.
408         */
409        private static void init_perm(long[][] perm, byte[] p, int chars_in, int chars_out) {
410            for (int k=0; k<chars_out*8; k++) {
411    
412                int l = p[k] - 1;
413                if (l < 0) continue;
414                int i = l>>2;
415                l = 1<<(l&0x03);
416                for (int j=0; j<16; j++) {
417                    int s = ((k&0x07)+((7-(k>>3))<<3));
418                    if ((j & l) != 0x00) perm[i][j] |= (1L<<s);
419                }
420            }
421        }
422            
423            /**
424             * Encrypts String into crypt (Unix) code.
425             * 
426             * @param key
427             *            the key to be encrypted
428             * @param setting
429             *            the salt to be used
430             * @return the encrypted String
431             */
432            @SuppressWarnings("deprecation")
433            public static String crypt(String key, String setting) {
434            long constdatablock = 0L;               /* encryption constant */
435            byte[] cryptresult = new byte[13];      /* encrypted result */
436            long keyword = 0L;
437            int keylen = key.length();
438    
439            for (int i=0; i<8 ; i++) {
440                keyword = (keyword << 8) | ((i < keylen)? 2*key.charAt(i): 0);
441            }
442    
443            long[] KS = des_setkey(keyword);
444    
445            int salt = 0;
446            for (int i=2; --i>=0;) {
447                char c = (i < setting.length())? setting.charAt(i): '.';
448                cryptresult[i] = (byte)c;
449                salt = (salt<<6) | (int)(0x00ff&A64TOI[c]);
450            }
451    
452            long rsltblock = des_cipher(constdatablock, salt, 25, KS);
453    
454            cryptresult[12] = ITOA64[(((int)rsltblock)<<2)&0x3f];
455            rsltblock >>= 4;
456            for (int i=12; --i>=2; ) {
457                cryptresult[i] = ITOA64[((int)rsltblock)&0x3f];
458                rsltblock >>= 6;
459            }
460    
461            return new String(cryptresult, 0x00, 0, 13);
462        }
463            
464            public CryptPasswordEncoder() {
465            }
466    
467            public static String encodePassword(char password[]) {
468                    long time = System.currentTimeMillis();
469                    return crypt(String.valueOf(password), Integer.toString(
470                                    (int) (time & 0xffffffffL), 16));
471            }
472            
473            public String encode(char[] password) {
474            return encodePassword(password);
475            }
476    
477            public boolean compare(String encoded, char[] plain) {
478                    String salt = encoded.substring(0, 2);
479                    return encoded.equals(crypt(String.valueOf(plain), salt));
480            }
481    
482            public static void main(String args[]) {
483                    for (int i = 0; i < args.length; i++) {
484                            System.out.println(args[i] + ": "
485                                            + encodePassword(args[i].toCharArray()));
486                    }
487            }
488    
489    }