1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 package org.apache.directory.api.util;
42
43
44 import org.apache.directory.api.i18n.I18n;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public class UnixCrypt extends Object
73 {
74
75
76 private static final byte[] IP =
77 {
78 58, 50, 42, 34, 26, 18, 10, 2,
79 60, 52, 44, 36, 28, 20, 12, 4,
80 62, 54, 46, 38, 30, 22, 14, 6,
81 64, 56, 48, 40, 32, 24, 16, 8,
82 57, 49, 41, 33, 25, 17, 9, 1,
83 59, 51, 43, 35, 27, 19, 11, 3,
84 61, 53, 45, 37, 29, 21, 13, 5,
85 63, 55, 47, 39, 31, 23, 15, 7 };
86
87
88 private static final byte[] ExpandTr =
89 {
90 32, 1, 2, 3, 4, 5,
91 4, 5, 6, 7, 8, 9,
92 8, 9, 10, 11, 12, 13,
93 12, 13, 14, 15, 16, 17,
94 16, 17, 18, 19, 20, 21,
95 20, 21, 22, 23, 24, 25,
96 24, 25, 26, 27, 28, 29,
97 28, 29, 30, 31, 32, 1 };
98
99 private static final byte[] PC1 =
100 {
101 57, 49, 41, 33, 25, 17, 9,
102 1, 58, 50, 42, 34, 26, 18,
103 10, 2, 59, 51, 43, 35, 27,
104 19, 11, 3, 60, 52, 44, 36,
105
106 63, 55, 47, 39, 31, 23, 15,
107 7, 62, 54, 46, 38, 30, 22,
108 14, 6, 61, 53, 45, 37, 29,
109 21, 13, 5, 28, 20, 12, 4 };
110
111 private static final byte[] Rotates =
112 {
113 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
114
115 private static final byte[] PC2 =
116 {
117 9, 18, 14, 17, 11, 24, 1, 5,
118 22, 25, 3, 28, 15, 6, 21, 10,
119 35, 38, 23, 19, 12, 4, 26, 8,
120 43, 54, 16, 7, 27, 20, 13, 2,
121
122 0, 0, 41, 52, 31, 37, 47, 55,
123 0, 0, 30, 40, 51, 45, 33, 48,
124 0, 0, 44, 49, 39, 56, 34, 53,
125 0, 0, 46, 42, 50, 36, 29, 32 };
126
127 private static final byte[][] S =
128 {
129
130 { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
131 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
132 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
133 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 },
134
135 { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
136 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
137 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
138 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 },
139
140 { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
141 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
142 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
143 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 },
144
145 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
146 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
147 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
148 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 },
149
150 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
151 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
152 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
153 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 },
154
155 { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
156 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
157 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
158 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 },
159
160 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
161 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
162 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
163 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 },
164
165 { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
166 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
167 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
168 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } };
169
170 private static final byte[] P32Tr =
171 {
172 16, 7, 20, 21,
173 29, 12, 28, 17,
174 1, 15, 23, 26,
175 5, 18, 31, 10,
176 2, 8, 24, 14,
177 32, 27, 3, 9,
178 19, 13, 30, 6,
179 22, 11, 4, 25 };
180
181 private static final byte[] CIFP =
182 {
183 1, 2, 3, 4, 17, 18, 19, 20,
184 5, 6, 7, 8, 21, 22, 23, 24,
185 9, 10, 11, 12, 25, 26, 27, 28,
186 13, 14, 15, 16, 29, 30, 31, 32,
187
188 33, 34, 35, 36, 49, 50, 51, 52,
189 37, 38, 39, 40, 53, 54, 55, 56,
190 41, 42, 43, 44, 57, 58, 59, 60,
191 45, 46, 47, 48, 61, 62, 63, 64 };
192
193 private static final byte[] ITOA64 =
194 {
195 ( byte ) '.',
196 ( byte ) '/',
197 ( byte ) '0',
198 ( byte ) '1',
199 ( byte ) '2',
200 ( byte ) '3',
201 ( byte ) '4',
202 ( byte ) '5',
203 ( byte ) '6',
204 ( byte ) '7',
205 ( byte ) '8',
206 ( byte ) '9',
207 ( byte ) 'A',
208 ( byte ) 'B',
209 ( byte ) 'C',
210 ( byte ) 'D',
211 ( byte ) 'E',
212 ( byte ) 'F',
213 ( byte ) 'G',
214 ( byte ) 'H',
215 ( byte ) 'I',
216 ( byte ) 'J',
217 ( byte ) 'K',
218 ( byte ) 'L',
219 ( byte ) 'M',
220 ( byte ) 'N',
221 ( byte ) 'O',
222 ( byte ) 'P',
223 ( byte ) 'Q',
224 ( byte ) 'R',
225 ( byte ) 'S',
226 ( byte ) 'T',
227 ( byte ) 'U',
228 ( byte ) 'V',
229 ( byte ) 'W',
230 ( byte ) 'X',
231 ( byte ) 'Y',
232 ( byte ) 'Z',
233 ( byte ) 'a',
234 ( byte ) 'b',
235 ( byte ) 'c',
236 ( byte ) 'd',
237 ( byte ) 'e',
238 ( byte ) 'f',
239 ( byte ) 'g',
240 ( byte ) 'h',
241 ( byte ) 'i',
242 ( byte ) 'j',
243 ( byte ) 'k',
244 ( byte ) 'l',
245 ( byte ) 'm',
246 ( byte ) 'n',
247 ( byte ) 'o',
248 ( byte ) 'p',
249 ( byte ) 'q',
250 ( byte ) 'r',
251 ( byte ) 's',
252 ( byte ) 't',
253 ( byte ) 'u',
254 ( byte ) 'v',
255 ( byte ) 'w',
256 ( byte ) 'x',
257 ( byte ) 'y',
258 ( byte ) 'z' };
259
260
261
262 private static byte[] A64TOI = new byte[128];
263
264
265 private static long[][] PC1ROT = new long[16][16];
266
267
268 private static long[][][] PC2ROT = new long[2][16][16];
269
270
271 private static long[][] IE3264 = new long[8][16];
272
273
274 private static long[][] SPE = new long[8][64];
275
276
277 private static long[][] CF6464 = new long[16][16];
278
279
280
281 static
282 {
283 byte[] perm = new byte[64];
284 byte[] temp = new byte[64];
285
286
287 for ( int i = 0; i < 64; i++ )
288 {
289 A64TOI[ITOA64[i]] = ( byte ) i;
290 }
291
292
293 for ( int i = 0; i < 64; i++ )
294 {
295 perm[i] = ( byte ) 0;
296 }
297
298 for ( int i = 0; i < 64; i++ )
299 {
300 int k;
301
302 if ( ( k = PC2[i] ) == 0 )
303 {
304 continue;
305 }
306
307 k += Rotates[0] - 1;
308
309 if ( ( k % 28 ) < Rotates[0] )
310 {
311 k -= 28;
312 }
313
314 k = PC1[k];
315
316 if ( k > 0 )
317 {
318 k--;
319 k = ( k | 0x07 ) - ( k & 0x07 );
320 k++;
321 }
322
323 perm[i] = ( byte ) k;
324 }
325
326 init_perm( PC1ROT, perm, 8 );
327
328
329 for ( int j = 0; j < 2; j++ )
330 {
331 int k;
332
333 for ( int i = 0; i < 64; i++ )
334 {
335 perm[i] = temp[i] = 0;
336 }
337
338 for ( int i = 0; i < 64; i++ )
339 {
340 if ( ( k = PC2[i] ) == 0 )
341 {
342 continue;
343 }
344
345 temp[k - 1] = ( byte ) ( i + 1 );
346 }
347
348 for ( int i = 0; i < 64; i++ )
349 {
350 if ( ( k = PC2[i] ) == 0 )
351 {
352 continue;
353 }
354
355 k += j;
356
357 if ( ( k % 28 ) <= j )
358 {
359 k -= 28;
360 }
361
362 perm[i] = temp[k];
363 }
364
365 init_perm( PC2ROT[j], perm, 8 );
366 }
367
368
369 for ( int i = 0; i < 8; i++ )
370 {
371 for ( int j = 0; j < 8; j++ )
372 {
373 int k = ( j < 2 ) ? 0 : IP[ExpandTr[i * 6 + j - 2] - 1];
374
375 if ( k > 32 )
376 {
377 k -= 32;
378 }
379 else if ( k > 0 )
380 {
381 k--;
382 }
383
384 if ( k > 0 )
385 {
386 k--;
387 k = ( k | 0x07 ) - ( k & 0x07 );
388 k++;
389 }
390
391 perm[i * 8 + j] = ( byte ) k;
392 }
393 }
394
395 init_perm( IE3264, perm, 8 );
396
397
398 for ( int i = 0; i < 64; i++ )
399 {
400 int k = IP[CIFP[i] - 1];
401
402 if ( k > 0 )
403 {
404 k--;
405 k = ( k | 0x07 ) - ( k & 0x07 );
406 k++;
407 }
408
409 perm[k - 1] = ( byte ) ( i + 1 );
410 }
411
412 init_perm( CF6464, perm, 8 );
413
414
415 for ( int i = 0; i < 48; i++ )
416 {
417 perm[i] = P32Tr[ExpandTr[i] - 1];
418 }
419
420 for ( int t = 0; t < 8; t++ )
421 {
422 for ( int j = 0; j < 64; j++ )
423 {
424 int k = ( ( ( j >> 0 ) & 0x01 ) << 5 ) | ( ( ( j >> 1 ) & 0x01 ) << 3 ) |
425 ( ( ( j >> 2 ) & 0x01 ) << 2 ) | ( ( ( j >> 3 ) & 0x01 ) << 1 ) |
426 ( ( ( j >> 4 ) & 0x01 ) << 0 ) | ( ( ( j >> 5 ) & 0x01 ) << 4 );
427 k = S[t][k];
428 k = ( ( ( k >> 3 ) & 0x01 ) << 0 ) | ( ( ( k >> 2 ) & 0x01 ) << 1 ) |
429 ( ( ( k >> 1 ) & 0x01 ) << 2 ) | ( ( ( k >> 0 ) & 0x01 ) << 3 );
430
431 for ( int i = 0; i < 32; i++ )
432 {
433 temp[i] = 0;
434 }
435
436 for ( int i = 0; i < 4; i++ )
437 {
438 temp[4 * t + i] = ( byte ) ( ( k >> i ) & 0x01 );
439 }
440
441 long kk = 0;
442
443 for ( int i = 24; --i >= 0; )
444 {
445 kk = ( ( kk << 1 ) |
446 ( ( long ) temp[perm[i] - 1] ) << 32 |
447 ( temp[perm[i + 24] - 1] ) );
448 }
449
450 SPE[t][j] = to_six_bit( kk );
451 }
452 }
453 }
454
455
456
457
458
459 private UnixCrypt()
460 {
461 }
462
463
464
465
466
467
468 private static int to_six_bit( int num )
469 {
470 return ( ( ( num << 26 ) & 0xfc000000 ) | ( ( num << 12 ) & 0xfc0000 ) |
471 ( ( num >> 2 ) & 0xfc00 ) | ( ( num >> 16 ) & 0xfc ) );
472 }
473
474
475
476
477
478
479 private static long to_six_bit( long num )
480 {
481 return ( ( ( num << 26 ) & 0xfc000000fc000000L ) | ( ( num << 12 ) & 0xfc000000fc0000L ) |
482 ( ( num >> 2 ) & 0xfc000000fc00L ) | ( ( num >> 16 ) & 0xfc000000fcL ) );
483 }
484
485
486
487
488
489
490 private static long perm6464( long c, long[][] p )
491 {
492 long out = 0L;
493
494 for ( int i = 8; --i >= 0; )
495 {
496 int t = ( int ) ( 0x00ff & c );
497 c >>= 8;
498 long tp = p[i << 1][t & 0x0f];
499 out |= tp;
500 tp = p[( i << 1 ) + 1][t >> 4];
501 out |= tp;
502 }
503
504 return out;
505 }
506
507
508
509
510
511
512 private static long perm3264( int c, long[][] p )
513 {
514 long out = 0L;
515
516 for ( int i = 4; --i >= 0; )
517 {
518 int t = ( 0x00ff & c );
519 c >>= 8;
520 long tp = p[i << 1][t & 0x0f];
521 out |= tp;
522 tp = p[( i << 1 ) + 1][t >> 4];
523 out |= tp;
524 }
525
526 return out;
527 }
528
529
530
531
532
533 private static long[] des_setkey( long keyword )
534 {
535 long K = perm6464( keyword, PC1ROT );
536 long[] KS = new long[16];
537 KS[0] = K & ~0x0303030300000000L;
538
539 for ( int i = 1; i < 16; i++ )
540 {
541 KS[i] = K;
542 K = perm6464( K, PC2ROT[Rotates[i] - 1] );
543
544 KS[i] = K & ~0x0303030300000000L;
545 }
546 return KS;
547 }
548
549
550
551
552
553
554 private static long des_cipher( long in, int salt, int num_iter, long[] KS )
555 {
556 salt = to_six_bit( salt );
557 long L = in;
558 long R = L;
559 L &= 0x5555555555555555L;
560 R = ( R & 0xaaaaaaaa00000000L ) | ( ( R >> 1 ) & 0x0000000055555555L );
561 L = ( ( ( ( L << 1 ) | ( L << 32 ) ) & 0xffffffff00000000L ) |
562 ( ( R | ( R >> 32 ) ) & 0x00000000ffffffffL ) );
563
564 L = perm3264( ( int ) ( L >> 32 ), IE3264 );
565 R = perm3264( ( int ) ( L & 0xffffffff ), IE3264 );
566
567 while ( --num_iter >= 0 )
568 {
569 for ( int loop_count = 0; loop_count < 8; loop_count++ )
570 {
571 long kp;
572 long B;
573 long k;
574
575 kp = KS[( loop_count << 1 )];
576 k = ( ( R >> 32 ) ^ R ) & salt & 0xffffffffL;
577 k |= ( k << 32 );
578 B = ( k ^ R ^ kp );
579
580 L ^= ( SPE[0][( int ) ( ( B >> 58 ) & 0x3f )] ^ SPE[1][( int ) ( ( B >> 50 ) & 0x3f )] ^
581 SPE[2][( int ) ( ( B >> 42 ) & 0x3f )] ^ SPE[3][( int ) ( ( B >> 34 ) & 0x3f )] ^
582 SPE[4][( int ) ( ( B >> 26 ) & 0x3f )] ^ SPE[5][( int ) ( ( B >> 18 ) & 0x3f )] ^
583 SPE[6][( int ) ( ( B >> 10 ) & 0x3f )] ^ SPE[7][( int ) ( ( B >> 2 ) & 0x3f )] );
584
585 kp = KS[( loop_count << 1 ) + 1];
586 k = ( ( L >> 32 ) ^ L ) & salt & 0xffffffffL;
587 k |= ( k << 32 );
588 B = ( k ^ L ^ kp );
589
590 R ^= ( SPE[0][( int ) ( ( B >> 58 ) & 0x3f )] ^ SPE[1][( int ) ( ( B >> 50 ) & 0x3f )] ^
591 SPE[2][( int ) ( ( B >> 42 ) & 0x3f )] ^ SPE[3][( int ) ( ( B >> 34 ) & 0x3f )] ^
592 SPE[4][( int ) ( ( B >> 26 ) & 0x3f )] ^ SPE[5][( int ) ( ( B >> 18 ) & 0x3f )] ^
593 SPE[6][( int ) ( ( B >> 10 ) & 0x3f )] ^ SPE[7][( int ) ( ( B >> 2 ) & 0x3f )] );
594 }
595
596 L ^= R;
597 R ^= L;
598 L ^= R;
599 }
600 L = ( ( ( ( L >> 35 ) & 0x0f0f0f0fL ) | ( ( ( L & 0xffffffff ) << 1 ) & 0xf0f0f0f0L ) ) << 32 |
601 ( ( ( R >> 35 ) & 0x0f0f0f0fL ) | ( ( ( R & 0xffffffff ) << 1 ) & 0xf0f0f0f0L ) ) );
602
603 L = perm6464( L, CF6464 );
604
605 return L;
606 }
607
608
609
610
611
612 private static void init_perm( long[][] perm, byte[] p, int chars_out )
613 {
614 for ( int k = 0; k < chars_out * 8; k++ )
615 {
616
617 int l = p[k] - 1;
618
619 if ( l < 0 )
620 {
621 continue;
622 }
623
624 int i = l >> 2;
625 l = 1 << ( l & 0x03 );
626
627 for ( int j = 0; j < 16; j++ )
628 {
629 int s = ( ( k & 0x07 ) + ( ( 7 - ( k >> 3 ) ) << 3 ) );
630
631 if ( ( j & l ) != 0x00 )
632 {
633 perm[i][j] |= ( 1L << s );
634 }
635 }
636 }
637 }
638
639
640
641
642
643
644
645
646 @SuppressWarnings("deprecation")
647 public static String crypt( String key, String setting )
648 {
649 long constdatablock = 0L;
650 byte[] cryptresult = new byte[13];
651 long keyword = 0L;
652
653
654 if ( key == null || setting == null )
655 {
656 return "*";
657 }
658
659 int keylen = key.length();
660
661 for ( int i = 0; i < 8; i++ )
662 {
663 keyword = ( keyword << 8 ) | ( ( i < keylen ) ? 2 * key.charAt( i ) : 0 );
664 }
665
666 long[] KS = des_setkey( keyword );
667
668 int salt = 0;
669
670 for ( int i = 2; --i >= 0; )
671 {
672 char c = ( i < setting.length() ) ? setting.charAt( i ) : '.';
673 cryptresult[i] = ( byte ) c;
674 salt = ( salt << 6 ) | ( 0x00ff & A64TOI[c] );
675 }
676
677 long rsltblock = des_cipher( constdatablock, salt, 25, KS );
678
679 cryptresult[12] = ITOA64[( ( ( int ) rsltblock ) << 2 ) & 0x3f];
680 rsltblock >>= 4;
681
682 for ( int i = 12; --i >= 2; )
683 {
684 cryptresult[i] = ITOA64[( ( int ) rsltblock ) & 0x3f];
685 rsltblock >>= 6;
686 }
687
688 return new String( cryptresult, 0x00, 0, 13 );
689 }
690
691
692 public static void main( String[] arg )
693 {
694 if ( arg.length != 2 )
695 {
696 System.err.println( I18n.err( I18n.ERR_04439 ) );
697 System.exit( 1 );
698 }
699
700 System.err.println( I18n.err( I18n.ERR_04440, crypt( arg[0], arg[1] ) ) );
701 }
702 }