View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.util;
16  
17  /**
18   * Unix Crypt. Implements the one way cryptography used by Unix systems for
19   * simple password protection. This class has been extracted from
20   * <a href="http://jetty.mortbay.org">Jetty</a> package.<br/>
21   *
22   * Copyright (c) 1996 Aki Yoshida. All rights reserved.<br/>
23   *
24   * Permission to use, copy, modify and distribute this software for
25   * non-commercial or commercial purposes and without fee is hereby granted
26   * provided that this copyright notice appears in all copies.
27   *
28   * @version 0.9, 11/25/96 - $Revision: 1.3 $
29   * @author Aki Yoshida
30   *
31   * modified April 2001
32   * by Iris Van den Broeke, Daniel Deville
33   */
34  public class UnixCrypt{
35  
36     // Attributes ---------------------------------------------------------------
37     
38     /* (mostly) Standard DES Tables from Tom Truscott */
39     private static final byte[] IP = {     /* initial permutation */
40        58, 50, 42, 34, 26, 18, 10,  2,
41        60, 52, 44, 36, 28, 20, 12,  4,
42        62, 54, 46, 38, 30, 22, 14,  6,
43        64, 56, 48, 40, 32, 24, 16,  8,
44        57, 49, 41, 33, 25, 17,  9,  1,
45        59, 51, 43, 35, 27, 19, 11,  3,
46        61, 53, 45, 37, 29, 21, 13,  5,
47        63, 55, 47, 39, 31, 23, 15,  7};
48  
49     /* The final permutation is the inverse of IP - no table is necessary */
50     private static final byte[] ExpandTr = {  /* expansion operation */
51        32,  1,  2,  3,  4,  5,
52        4,  5,  6,  7,  8,  9,
53        8,  9, 10, 11, 12, 13,
54        12, 13, 14, 15, 16, 17,
55        16, 17, 18, 19, 20, 21,
56        20, 21, 22, 23, 24, 25,
57        24, 25, 26, 27, 28, 29,
58        28, 29, 30, 31, 32,  1};
59  
60     private static final byte[] PC1 = {    /* permuted choice table 1 */
61        57, 49, 41, 33, 25, 17,  9,
62        1, 58, 50, 42, 34, 26, 18,
63        10,  2, 59, 51, 43, 35, 27,
64        19, 11,  3, 60, 52, 44, 36,      
65        63, 55, 47, 39, 31, 23, 15,
66        7, 62, 54, 46, 38, 30, 22,
67        14,  6, 61, 53, 45, 37, 29,
68        21, 13,  5, 28, 20, 12,  4};
69  
70     /* PC1 rotation schedule */
71     private static final byte[] Rotates = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
72  
73     private static final byte[] PC2 = {    /* permuted choice table 2 */
74        9, 18,    14, 17, 11, 24,  1,  5,
75        22, 25,     3, 28, 15,  6, 21, 10,
76        35, 38,    23, 19, 12,  4, 26,  8,
77        43, 54,    16,  7, 27, 20, 13,  2,      
78        0,  0,    41, 52, 31, 37, 47, 55,
79        0,  0,    30, 40, 51, 45, 33, 48,
80        0,  0,    44, 49, 39, 56, 34, 53,
81        0,  0,    46, 42, 50, 36, 29, 32};
82  
83     private static final byte[][] S = {    /* 48->32 bit substitution tables */
84        /* S[1] */
85        {14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
86         0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
87         4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
88         15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13},
89         /* S[2] */
90         {15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
91          3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
92          0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
93          13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9},
94          /* S[3] */
95          {10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
96           13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
97           13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
98           1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12},
99           /* S[4] */
100          {7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
101           13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
102           10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
103           3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14},
104           /* S[5] */
105           {2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
106            14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
107            4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
108            11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3},
109            /* S[6] */
110            {12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
111             10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
112             9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
113             4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13},
114             /* S[7] */
115             {4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
116              13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
117              1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
118              6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12},
119              /* S[8]	*/
120              {13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
121               1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
122               7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
123               2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}};
124 
125    private static final byte[] P32Tr = {     /* 32-bit permutation function */
126       16,  7, 20, 21,
127       29, 12, 28, 17,
128       1, 15, 23, 26,
129       5, 18, 31, 10,
130       2,  8, 24, 14,
131       32, 27,  3,  9,
132       19, 13, 30,  6,
133       22, 11,  4, 25};
134 
135    private static final byte[] CIFP = {      /* compressed/interleaved permutation */
136       1,  2,  3,  4,   17, 18, 19, 20,
137       5,  6,  7,  8,   21, 22, 23, 24,
138       9, 10, 11, 12,   25, 26, 27, 28,
139       13, 14, 15, 16,   29, 30, 31, 32,      
140       33, 34, 35, 36,   49, 50, 51, 52,
141       37, 38, 39, 40,   53, 54, 55, 56,
142       41, 42, 43, 44,   57, 58, 59, 60,
143       45, 46, 47, 48,   61, 62, 63, 64};
144 
145    private static final byte[] ITOA64 = {    /* 0..63 => ascii-64 */
146       (byte)'.', (byte)'/', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
147       (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D',
148       (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L',
149       (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T',
150       (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b',
151       (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j',
152       (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r',
153       (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z'};
154 
155       
156    /* =====  Tables that are initialized at run time  ==================== */
157 
158    private static byte[] A64TOI = new byte[128];   /* ascii-64 => 0..63 */
159       
160    /* Initial key schedule permutation */
161    private static long[][] PC1ROT = new long[16][16];
162 
163    /* Subsequent key schedule rotation permutations */
164    private static long[][][] PC2ROT = new long[2][16][16];
165 
166    /* Initial permutation/expansion table */
167    private static long[][] IE3264 = new long[8][16];
168 
169    /* Table that combines the S, P, and E operations.  */
170    private static long[][] SPE = new long[8][64];
171 
172    /* compressed/interleaved => final permutation table */
173    private static long[][] CF6464 = new long[16][16];
174 
175    /* ==================================== */
176    
177    static {
178       byte[] perm = new byte[64];
179       byte[] temp = new byte[64];
180       
181       // inverse table.
182       for (int i=0; i<64; i++) A64TOI[ITOA64[i]] = (byte)i;
183       
184       // PC1ROT - bit reverse, then PC1, then Rotate, then PC2
185       for (int i=0; i<64; i++) perm[i] = (byte)0;;
186       for (int i=0; i<64; i++) {
187          int k;
188          if ((k = (int)PC2[i]) == 0) continue;
189          k += Rotates[0]-1;
190          if ((k%28) < Rotates[0]) k -= 28;
191          k = (int)PC1[k];
192          if (k > 0) {
193             k--;
194             k = (k|0x07) - (k&0x07);
195             k++;
196          }
197          perm[i] = (byte)k;
198       }
199       init_perm(PC1ROT, perm, 8, 8);
200       
201       // PC2ROT - PC2 inverse, then Rotate, then PC2
202       for (int j=0; j<2; j++) {
203          int k;
204          for (int i=0; i<64; i++) perm[i] = temp[i] = 0;
205          for (int i=0; i<64; i++) {
206             if ((k = (int)PC2[i]) == 0) continue;
207             temp[k-1] = (byte)(i+1);
208          }
209          for (int i=0; i<64; i++) {
210             if ((k = (int)PC2[i]) == 0) continue;
211             k += j;
212             if ((k%28) <= j) k -= 28;
213             perm[i] = temp[k];
214          }
215          
216          init_perm(PC2ROT[j], perm, 8, 8);
217       }
218       
219       // Bit reverse, intial permupation, expantion
220       for (int i=0; i<8; i++) {
221          for (int j=0; j<8; j++) {
222             int k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
223             if (k > 32) k -= 32;
224             else if (k > 0) k--;
225             if (k > 0) {
226                k--;
227                k = (k|0x07) - (k&0x07);
228                k++;
229             }
230             perm[i*8+j] = (byte)k;
231          }
232       }
233       
234       init_perm(IE3264, perm, 4, 8);
235       
236       // Compression, final permutation, bit reverse
237       for (int i=0; i<64; i++) {
238          int k = IP[CIFP[i]-1];
239          if (k > 0) {
240             k--;
241             k = (k|0x07) - (k&0x07);
242             k++;
243          }
244          perm[k-1] = (byte)(i+1);
245       }
246       
247       init_perm(CF6464, perm, 8, 8);
248       
249       // SPE table
250       for (int i=0; i<48; i++)
251          perm[i] = P32Tr[ExpandTr[i]-1];
252       for (int t=0; t<8; t++) {
253          for (int j=0; j<64; j++) {
254             int k = (((j >> 0) & 0x01) << 5) | (((j >> 1) & 0x01) << 3) |
255             (((j >> 2) & 0x01) << 2) | (((j >> 3) & 0x01) << 1) |
256             (((j >> 4) & 0x01) << 0) | (((j >> 5) & 0x01) << 4);
257             k = S[t][k];
258             k = (((k >> 3) & 0x01) << 0) | (((k >> 2) & 0x01) << 1) |
259             (((k >> 1) & 0x01) << 2) | (((k >> 0) & 0x01) << 3);
260             for (int i=0; i<32; i++) temp[i] = 0;
261             for (int i=0; i<4; i++) temp[4*t+i] = (byte)((k >> i) & 0x01);
262             long kk = 0;
263             for (int i=24; --i>=0; ) kk = ((kk<<1) |
264             ((long)temp[perm[i]-1])<<32 |
265             ((long)temp[perm[i+24]-1]));
266             
267             SPE[t][j] = to_six_bit(kk);
268          }
269       }
270    }
271    
272    
273    // Constructors -------------------------------------------------------------
274    
275    /**
276     * You can't call the constructer.
277     */
278    private UnixCrypt() { }
279    
280    
281    // Private ------------------------------------------------------------------
282    
283    /**
284     * Returns the transposed and split code of a 24-bit code
285     * into a 4-byte code, each having 6 bits.
286     */
287    private static int to_six_bit(int num){
288       return (((num << 26) & 0xfc000000) | ((num << 12) & 0xfc0000) |
289       ((num >> 2) & 0xfc00) | ((num >> 16) & 0xfc));
290    }
291    
292    /**
293     * Returns the transposed and split code of two 24-bit code
294     * into two 4-byte code, each having 6 bits.
295     */
296    private static long to_six_bit(long num){
297       return (((num << 26) & 0xfc000000fc000000L) | ((num << 12) & 0xfc000000fc0000L) |
298       ((num >> 2) & 0xfc000000fc00L) | ((num >> 16) & 0xfc000000fcL));
299    }
300    
301    /**
302     * Returns the permutation of the given 64-bit code with
303     * the specified permutataion table.
304     */
305    private static long perm6464(long c, long[][]p){
306       long out = 0L;
307       for (int i=8; --i>=0; ) {
308          int t = (int)(0x00ff & c);
309          c >>= 8;
310          long tp = p[i<<1][t&0x0f];
311          out |= tp;
312          tp = p[(i<<1)+1][t>>4];
313          out |= tp;
314       }
315       return out;
316    }
317    
318    /**
319     * Returns the permutation of the given 32-bit code with
320     * the specified permutataion table.
321     */
322    private static long perm3264(int c, long[][]p){
323       long out = 0L;
324       for (int i=4; --i>=0; ) {
325          int t = (int)(0x00ff & c);
326          c >>= 8;
327          long tp = p[i<<1][t&0x0f];
328          out |= tp;
329          tp = p[(i<<1)+1][t>>4];
330          out |= tp;
331       }
332       return out;
333    }
334    
335    /**
336     * Returns the key schedule for the given key.
337     */
338    private static long[] des_setkey(long keyword){
339       long K = perm6464(keyword, PC1ROT);
340       long[] KS = new long[16];
341       KS[0] = K&~0x0303030300000000L;
342       
343       for (int i=1; i<16; i++) {
344          KS[i] = K;
345          K = perm6464(K, PC2ROT[Rotates[i]-1]);
346          
347          KS[i] = K&~0x0303030300000000L;
348       }
349       return KS;
350    }
351    
352    /**
353     * Returns the DES encrypted code of the given word with the specified
354     * environment.
355     */
356    private static long des_cipher(long in, int salt, int num_iter, long[] KS){
357       salt = to_six_bit(salt);
358       long L = in;
359       long R = L;
360       L &= 0x5555555555555555L;
361       R = (R & 0xaaaaaaaa00000000L) | ((R >> 1) & 0x0000000055555555L);
362       L = ((((L << 1) | (L << 32)) & 0xffffffff00000000L) |
363       ((R | (R >> 32)) & 0x00000000ffffffffL));
364       
365       L = perm3264((int)(L>>32), IE3264);
366       R = perm3264((int)(L&0xffffffff), IE3264);
367       
368       while (--num_iter >= 0) {
369          for (int loop_count=0; loop_count<8; loop_count++) {
370             long kp;
371             long B;
372             long k;
373             
374             kp = KS[(loop_count<<1)];
375             k = ((R>>32) ^ R) & salt & 0xffffffffL;
376             k |= (k<<32);
377             B = (k ^ R ^ kp);
378             
379             L ^= (SPE[0][(int)((B>>58)&0x3f)] ^ SPE[1][(int)((B>>50)&0x3f)] ^
380             SPE[2][(int)((B>>42)&0x3f)] ^ SPE[3][(int)((B>>34)&0x3f)] ^
381             SPE[4][(int)((B>>26)&0x3f)] ^ SPE[5][(int)((B>>18)&0x3f)] ^
382             SPE[6][(int)((B>>10)&0x3f)] ^ SPE[7][(int)((B>>2)&0x3f)]);
383             
384             kp = KS[(loop_count<<1)+1];
385             k = ((L>>32) ^ L) & salt & 0xffffffffL;
386             k |= (k<<32);
387             B = (k ^ L ^ kp);
388             
389             R ^= (SPE[0][(int)((B>>58)&0x3f)] ^ SPE[1][(int)((B>>50)&0x3f)] ^
390             SPE[2][(int)((B>>42)&0x3f)] ^ SPE[3][(int)((B>>34)&0x3f)] ^
391             SPE[4][(int)((B>>26)&0x3f)] ^ SPE[5][(int)((B>>18)&0x3f)] ^
392             SPE[6][(int)((B>>10)&0x3f)] ^ SPE[7][(int)((B>>2)&0x3f)]);
393          }
394          // swap L and R
395          L ^= R;
396          R ^= L;
397          L ^= R;
398       }
399       L = ((((L>>35) & 0x0f0f0f0fL) | (((L&0xffffffff)<<1) & 0xf0f0f0f0L))<<32 |
400       (((R>>35) & 0x0f0f0f0fL) | (((R&0xffffffff)<<1) & 0xf0f0f0f0L)));
401       
402       L = perm6464(L, CF6464);
403       
404       return L;
405    }
406    
407    /**
408     * Initializes the given permutation table with the mapping table.
409     */
410    private static void init_perm(long[][] perm, byte[] p, int chars_in, int chars_out){
411       for (int k=0; k<chars_out*8; k++) {
412          
413          int l = p[k] - 1;
414          if (l < 0) continue;
415          int i = l>>2;
416          l = 1<<(l&0x03);
417          for (int j=0; j<16; j++) {
418             int s = ((k&0x07)+((7-(k>>3))<<3));
419             if ((j & l) != 0x00) perm[i][j] |= (1L<<s);
420          }
421       }
422    }
423    
424    
425    // Public -------------------------------------------------------------------
426    
427    /**
428     * Encrypts String into crypt (Unix) code.
429     * @param key the key to be encrypted
430     * @param setting the salt to be used
431     * @return the encrypted String
432     */
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    /**
465     * Convenient method for command line usage.
466     * @param arg Array of arguments (key, value)
467     */
468    public static void main(String[] arg){
469       if (arg.length!=2) {
470          System.err.println("Usage - java c.m.U.UnixCrypt <key> <value>");
471          System.exit(1);
472       }
473       
474       System.err.println("Crypt=" + crypt(arg[0], arg[1]));
475    }
476 }