1 61 package jcifs.util; 62 63 import java.io.*; 64 65 72 73 public class DES { 74 75 76 private int[] encryptKeys = new int[32]; 77 private int[] decryptKeys = new int[32]; 78 79 private int[] tempInts = new int[2]; 80 81 82 public DES( ) { 83 84 } 85 86 public DES( byte[] key ) { 88 if( key.length == 7 ) { 89 byte[] key8 = new byte[8]; 90 makeSMBKey( key, key8 ); 91 setKey( key8 ); 92 } else { 93 setKey( key ); 94 } 95 } 96 97 98 public static void makeSMBKey(byte[] key7, byte[] key8) { 99 100 int i; 101 102 key8[0] = (byte) ( ( key7[0] >> 1) & 0xff); 103 key8[1] = (byte)(( ((key7[0] & 0x01) << 6) | (((key7[1] & 0xff)>>2) & 0xff)) & 0xff ); 104 key8[2] = (byte)(( ((key7[1] & 0x03) << 5) | (((key7[2] & 0xff)>>3) & 0xff)) & 0xff ); 105 key8[3] = (byte)(( ((key7[2] & 0x07) << 4) | (((key7[3] & 0xff)>>4) & 0xff)) & 0xff ); 106 key8[4] = (byte)(( ((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff)>>5) & 0xff)) & 0xff ); 107 key8[5] = (byte)(( ((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff)>>6) & 0xff)) & 0xff ); 108 key8[6] = (byte)(( ((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff)>>7) & 0xff)) & 0xff ); 109 key8[7] = (byte)(key7[6] & 0x7F); 110 for (i=0;i<8;i++) { 111 key8[i] = (byte)( key8[i] << 1); 112 } 113 } 114 115 public void setKey( byte[] key ) { 117 118 deskey( key, true, encryptKeys ); 120 deskey( key, false, decryptKeys ); 121 } 122 123 private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) { 125 126 int i, j, l, m, n; 127 int[] pc1m = new int[56]; 128 int[] pcr = new int[56]; 129 int[] kn = new int[32]; 130 131 for ( j = 0; j < 56; ++j ) { 132 l = pc1[j]; 133 m = l & 07; 134 pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0; 135 } 136 137 for ( i = 0; i < 16; ++i ) { 138 139 if ( encrypting ) 140 m = i << 1; 141 else 142 m = (15-i) << 1; 143 n = m+1; 144 kn[m] = kn[n] = 0; 145 for ( j = 0; j < 28; ++j ) { 146 l = j+totrot[i]; 147 if ( l < 28 ) 148 pcr[j] = pc1m[l]; 149 else 150 pcr[j] = pc1m[l-28]; 151 } 152 for ( j=28; j < 56; ++j ) { 153 l = j+totrot[i]; 154 if ( l < 56 ) 155 pcr[j] = pc1m[l]; 156 else 157 pcr[j] = pc1m[l-28]; 158 } 159 for ( j = 0; j < 24; ++j ) { 160 if ( pcr[pc2[j]] != 0 ) 161 kn[m] |= bigbyte[j]; 162 if ( pcr[pc2[j+24]] != 0 ) 163 kn[n] |= bigbyte[j]; 164 } 165 } 166 cookey( kn, KnL ); 167 } 168 169 private void cookey( int[] raw, int KnL[] ) { 170 int raw0, raw1; 171 int rawi, KnLi; 172 int i; 173 174 for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) { 175 raw0 = raw[rawi++]; 176 raw1 = raw[rawi++]; 177 KnL[KnLi] = (raw0 & 0x00fc0000) << 6; 178 KnL[KnLi] |= (raw0 & 0x00000fc0) << 10; 179 KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10; 180 KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6; 181 ++KnLi; 182 KnL[KnLi] = (raw0 & 0x0003f000) << 12; 183 KnL[KnLi] |= (raw0 & 0x0000003f) << 16; 184 KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4; 185 KnL[KnLi] |= (raw1 & 0x0000003f); 186 ++KnLi; 187 } 188 } 189 190 191 private void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) { 193 194 squashBytesToInts( clearText, clearOff, tempInts, 0, 2 ); 195 des( tempInts, tempInts, encryptKeys ); 196 spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 ); 197 } 198 199 private void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) { 201 202 squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 ); 203 des( tempInts, tempInts, decryptKeys ); 204 spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 ); 205 } 206 207 private void des( int[] inInts, int[] outInts, int[] keys ) { 209 210 int fval, work, right, leftt; 211 int round; 212 int keysi = 0; 213 214 leftt = inInts[0]; 215 right = inInts[1]; 216 217 work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f; 218 right ^= work; 219 leftt ^= (work << 4); 220 221 work = ((leftt >>> 16) ^ right) & 0x0000ffff; 222 right ^= work; 223 leftt ^= (work << 16); 224 225 work = ((right >>> 2) ^ leftt) & 0x33333333; 226 leftt ^= work; 227 right ^= (work << 2); 228 229 work = ((right >>> 8) ^ leftt) & 0x00ff00ff; 230 leftt ^= work; 231 right ^= (work << 8); 232 right = (right << 1) | ((right >>> 31) & 1); 233 234 work = (leftt ^ right) & 0xaaaaaaaa; 235 leftt ^= work; 236 right ^= work; 237 leftt = (leftt << 1) | ((leftt >>> 31) & 1); 238 239 for ( round = 0; round < 8; ++round ) { 240 work = (right << 28) | (right >>> 4); 241 work ^= keys[keysi++]; 242 fval = SP7[ work & 0x0000003f ]; 243 fval |= SP5[(work >>> 8) & 0x0000003f ]; 244 fval |= SP3[(work >>> 16) & 0x0000003f ]; 245 fval |= SP1[(work >>> 24) & 0x0000003f ]; 246 work = right ^ keys[keysi++]; 247 fval |= SP8[ work & 0x0000003f ]; 248 fval |= SP6[(work >>> 8) & 0x0000003f ]; 249 fval |= SP4[(work >>> 16) & 0x0000003f ]; 250 fval |= SP2[(work >>> 24) & 0x0000003f ]; 251 leftt ^= fval; 252 work = (leftt << 28) | (leftt >>> 4); 253 work ^= keys[keysi++]; 254 fval = SP7[ work & 0x0000003f ]; 255 fval |= SP5[(work >>> 8) & 0x0000003f ]; 256 fval |= SP3[(work >>> 16) & 0x0000003f ]; 257 fval |= SP1[(work >>> 24) & 0x0000003f ]; 258 work = leftt ^ keys[keysi++]; 259 fval |= SP8[ work & 0x0000003f ]; 260 fval |= SP6[(work >>> 8) & 0x0000003f ]; 261 fval |= SP4[(work >>> 16) & 0x0000003f ]; 262 fval |= SP2[(work >>> 24) & 0x0000003f ]; 263 right ^= fval; 264 } 265 266 right = (right << 31) | (right >>> 1); 267 work = (leftt ^ right) & 0xaaaaaaaa; 268 leftt ^= work; 269 right ^= work; 270 leftt = (leftt << 31) | (leftt >>> 1); 271 work = ((leftt >>> 8) ^ right) & 0x00ff00ff; 272 right ^= work; 273 leftt ^= (work << 8); 274 work = ((leftt >>> 2) ^ right) & 0x33333333; 275 right ^= work; 276 leftt ^= (work << 2); 277 work = ((right >>> 16) ^ leftt) & 0x0000ffff; 278 leftt ^= work; 279 right ^= (work << 16); 280 work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f; 281 leftt ^= work; 282 right ^= (work << 4); 283 outInts[0] = right; 284 outInts[1] = leftt; 285 } 286 287 288 public void encrypt( byte[] clearText, byte[] cipherText ) { 290 encrypt( clearText, 0, cipherText, 0 ); 291 } 292 293 public void decrypt( byte[] cipherText, byte[] clearText ) { 295 296 decrypt( cipherText, 0, clearText, 0 ); 297 } 298 299 302 public byte[] encrypt(byte[] clearText) { 303 304 int length = clearText.length; 305 306 if (length % 8 != 0) { 307 System.out.println("Array must be a multiple of 8"); 308 return null; 309 } 310 311 byte[] cipherText = new byte[length]; 312 int count = length / 8; 313 314 for (int i=0; i<count; i++) 315 encrypt(clearText, i*8, cipherText, i*8); 316 317 return cipherText; 318 } 319 320 323 public byte[] decrypt(byte[] cipherText) { 324 325 int length = cipherText.length; 326 327 if (length % 8 != 0) { 328 System.out.println("Array must be a multiple of 8"); 329 return null; 330 } 331 332 byte[] clearText = new byte[length]; 333 int count = length / 8; 334 335 for (int i=0; i<count; i++) 336 encrypt(cipherText, i*8, clearText, i*8); 337 338 return clearText; 339 } 340 341 342 344 private static byte[] bytebit = { 345 (byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10, 346 (byte)0x08, (byte)0x04, (byte)0x02, (byte)0x01 347 }; 348 private static int[] bigbyte = { 349 0x800000, 0x400000, 0x200000, 0x100000, 350 0x080000, 0x040000, 0x020000, 0x010000, 351 0x008000, 0x004000, 0x002000, 0x001000, 352 0x000800, 0x000400, 0x000200, 0x000100, 353 0x000080, 0x000040, 0x000020, 0x000010, 354 0x000008, 0x000004, 0x000002, 0x000001 355 }; 356 private static byte[] pc1 = { 357 (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8, 358 (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17, 359 (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26, 360 (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35, 361 (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14, 362 (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21, 363 (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28, 364 (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3 365 }; 366 private static int[] totrot = { 367 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 368 }; 369 370 private static byte[] pc2 = { 371 (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4, 372 (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9, 373 (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7, 374 (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1, 375 (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54, 376 (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47, 377 (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52, 378 (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31, 379 }; 380 381 private static int[] SP1 = { 382 0x01010400, 0x00000000, 0x00010000, 0x01010404, 383 0x01010004, 0x00010404, 0x00000004, 0x00010000, 384 0x00000400, 0x01010400, 0x01010404, 0x00000400, 385 0x01000404, 0x01010004, 0x01000000, 0x00000004, 386 0x00000404, 0x01000400, 0x01000400, 0x00010400, 387 0x00010400, 0x01010000, 0x01010000, 0x01000404, 388 0x00010004, 0x01000004, 0x01000004, 0x00010004, 389 0x00000000, 0x00000404, 0x00010404, 0x01000000, 390 0x00010000, 0x01010404, 0x00000004, 0x01010000, 391 0x01010400, 0x01000000, 0x01000000, 0x00000400, 392 0x01010004, 0x00010000, 0x00010400, 0x01000004, 393 0x00000400, 0x00000004, 0x01000404, 0x00010404, 394 0x01010404, 0x00010004, 0x01010000, 0x01000404, 395 0x01000004, 0x00000404, 0x00010404, 0x01010400, 396 0x00000404, 0x01000400, 0x01000400, 0x00000000, 397 0x00010004, 0x00010400, 0x00000000, 0x01010004 398 }; 399 private static int[] SP2 = { 400 0x80108020, 0x80008000, 0x00008000, 0x00108020, 401 0x00100000, 0x00000020, 0x80100020, 0x80008020, 402 0x80000020, 0x80108020, 0x80108000, 0x80000000, 403 0x80008000, 0x00100000, 0x00000020, 0x80100020, 404 0x00108000, 0x00100020, 0x80008020, 0x00000000, 405 0x80000000, 0x00008000, 0x00108020, 0x80100000, 406 0x00100020, 0x80000020, 0x00000000, 0x00108000, 407 0x00008020, 0x80108000, 0x80100000, 0x00008020, 408 0x00000000, 0x00108020, 0x80100020, 0x00100000, 409 0x80008020, 0x80100000, 0x80108000, 0x00008000, 410 0x80100000, 0x80008000, 0x00000020, 0x80108020, 411 0x00108020, 0x00000020, 0x00008000, 0x80000000, 412 0x00008020, 0x80108000, 0x00100000, 0x80000020, 413 0x00100020, 0x80008020, 0x80000020, 0x00100020, 414 0x00108000, 0x00000000, 0x80008000, 0x00008020, 415 0x80000000, 0x80100020, 0x80108020, 0x00108000 416 }; 417 private static int[] SP3 = { 418 0x00000208, 0x08020200, 0x00000000, 0x08020008, 419 0x08000200, 0x00000000, 0x00020208, 0x08000200, 420 0x00020008, 0x08000008, 0x08000008, 0x00020000, 421 0x08020208, 0x00020008, 0x08020000, 0x00000208, 422 0x08000000, 0x00000008, 0x08020200, 0x00000200, 423 0x00020200, 0x08020000, 0x08020008, 0x00020208, 424 0x08000208, 0x00020200, 0x00020000, 0x08000208, 425 0x00000008, 0x08020208, 0x00000200, 0x08000000, 426 0x08020200, 0x08000000, 0x00020008, 0x00000208, 427 0x00020000, 0x08020200, 0x08000200, 0x00000000, 428 0x00000200, 0x00020008, 0x08020208, 0x08000200, 429 0x08000008, 0x00000200, 0x00000000, 0x08020008, 430 0x08000208, 0x00020000, 0x08000000, 0x08020208, 431 0x00000008, 0x00020208, 0x00020200, 0x08000008, 432 0x08020000, 0x08000208, 0x00000208, 0x08020000, 433 0x00020208, 0x00000008, 0x08020008, 0x00020200 434 }; 435 private static int[] SP4 = { 436 0x00802001, 0x00002081, 0x00002081, 0x00000080, 437 0x00802080, 0x00800081, 0x00800001, 0x00002001, 438 0x00000000, 0x00802000, 0x00802000, 0x00802081, 439 0x00000081, 0x00000000, 0x00800080, 0x00800001, 440 0x00000001, 0x00002000, 0x00800000, 0x00802001, 441 0x00000080, 0x00800000, 0x00002001, 0x00002080, 442 0x00800081, 0x00000001, 0x00002080, 0x00800080, 443 0x00002000, 0x00802080, 0x00802081, 0x00000081, 444 0x00800080, 0x00800001, 0x00802000, 0x00802081, 445 0x00000081, 0x00000000, 0x00000000, 0x00802000, 446 0x00002080, 0x00800080, 0x00800081, 0x00000001, 447 0x00802001, 0x00002081, 0x00002081, 0x00000080, 448 0x00802081, 0x00000081, 0x00000001, 0x00002000, 449 0x00800001, 0x00002001, 0x00802080, 0x00800081, 450 0x00002001, 0x00002080, 0x00800000, 0x00802001, 451 0x00000080, 0x00800000, 0x00002000, 0x00802080 452 }; 453 private static int[] SP5 = { 454 0x00000100, 0x02080100, 0x02080000, 0x42000100, 455 0x00080000, 0x00000100, 0x40000000, 0x02080000, 456 0x40080100, 0x00080000, 0x02000100, 0x40080100, 457 0x42000100, 0x42080000, 0x00080100, 0x40000000, 458 0x02000000, 0x40080000, 0x40080000, 0x00000000, 459 0x40000100, 0x42080100, 0x42080100, 0x02000100, 460 0x42080000, 0x40000100, 0x00000000, 0x42000000, 461 0x02080100, 0x02000000, 0x42000000, 0x00080100, 462 0x00080000, 0x42000100, 0x00000100, 0x02000000, 463 0x40000000, 0x02080000, 0x42000100, 0x40080100, 464 0x02000100, 0x40000000, 0x42080000, 0x02080100, 465 0x40080100, 0x00000100, 0x02000000, 0x42080000, 466 0x42080100, 0x00080100, 0x42000000, 0x42080100, 467 0x02080000, 0x00000000, 0x40080000, 0x42000000, 468 0x00080100, 0x02000100, 0x40000100, 0x00080000, 469 0x00000000, 0x40080000, 0x02080100, 0x40000100 470 }; 471 private static int[] SP6 = { 472 0x20000010, 0x20400000, 0x00004000, 0x20404010, 473 0x20400000, 0x00000010, 0x20404010, 0x00400000, 474 0x20004000, 0x00404010, 0x00400000, 0x20000010, 475 0x00400010, 0x20004000, 0x20000000, 0x00004010, 476 0x00000000, 0x00400010, 0x20004010, 0x00004000, 477 0x00404000, 0x20004010, 0x00000010, 0x20400010, 478 0x20400010, 0x00000000, 0x00404010, 0x20404000, 479 0x00004010, 0x00404000, 0x20404000, 0x20000000, 480 0x20004000, 0x00000010, 0x20400010, 0x00404000, 481 0x20404010, 0x00400000, 0x00004010, 0x20000010, 482 0x00400000, 0x20004000, 0x20000000, 0x00004010, 483 0x20000010, 0x20404010, 0x00404000, 0x20400000, 484 0x00404010, 0x20404000, 0x00000000, 0x20400010, 485 0x00000010, 0x00004000, 0x20400000, 0x00404010, 486 0x00004000, 0x00400010, 0x20004010, 0x00000000, 487 0x20404000, 0x20000000, 0x00400010, 0x20004010 488 }; 489 private static int[] SP7 = { 490 0x00200000, 0x04200002, 0x04000802, 0x00000000, 491 0x00000800, 0x04000802, 0x00200802, 0x04200800, 492 0x04200802, 0x00200000, 0x00000000, 0x04000002, 493 0x00000002, 0x04000000, 0x04200002, 0x00000802, 494 0x04000800, 0x00200802, 0x00200002, 0x04000800, 495 0x04000002, 0x04200000, 0x04200800, 0x00200002, 496 0x04200000, 0x00000800, 0x00000802, 0x04200802, 497 0x00200800, 0x00000002, 0x04000000, 0x00200800, 498 0x04000000, 0x00200800, 0x00200000, 0x04000802, 499 0x04000802, 0x04200002, 0x04200002, 0x00000002, 500 0x00200002, 0x04000000, 0x04000800, 0x00200000, 501 0x04200800, 0x00000802, 0x00200802, 0x04200800, 502 0x00000802, 0x04000002, 0x04200802, 0x04200000, 503 0x00200800, 0x00000000, 0x00000002, 0x04200802, 504 0x00000000, 0x00200802, 0x04200000, 0x00000800, 505 0x04000002, 0x04000800, 0x00000800, 0x00200002 506 }; 507 private static int[] SP8 = { 508 0x10001040, 0x00001000, 0x00040000, 0x10041040, 509 0x10000000, 0x10001040, 0x00000040, 0x10000000, 510 0x00040040, 0x10040000, 0x10041040, 0x00041000, 511 0x10041000, 0x00041040, 0x00001000, 0x00000040, 512 0x10040000, 0x10000040, 0x10001000, 0x00001040, 513 0x00041000, 0x00040040, 0x10040040, 0x10041000, 514 0x00001040, 0x00000000, 0x00000000, 0x10040040, 515 0x10000040, 0x10001000, 0x00041040, 0x00040000, 516 0x00041040, 0x00040000, 0x10041000, 0x00001000, 517 0x00000040, 0x10040040, 0x00001000, 0x00041040, 518 0x10001000, 0x00000040, 0x10000040, 0x10040000, 519 0x10040040, 0x10000000, 0x00040000, 0x10001040, 520 0x00000000, 0x10041040, 0x00040040, 0x10000040, 521 0x10040000, 0x10001000, 0x10001040, 0x00000000, 522 0x10041040, 0x00041000, 0x00041000, 0x00001040, 523 0x00001040, 0x00040040, 0x10000000, 0x10041000 524 }; 525 526 527 public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, 529 int outOff, int intLen ) { 530 531 for ( int i = 0; i < intLen; ++i ) 532 outInts[outOff + i] = 533 ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) | 534 ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) | 535 ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) | 536 ( inBytes[inOff + i * 4 + 3] & 0xff ); 537 } 538 539 public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, 541 int outOff, int intLen ) { 542 543 for ( int i = 0; i < intLen; ++i ) { 544 545 outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 ); 546 outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 ); 547 outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 ); 548 outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i]; 549 } 550 } 551 } 552 | Popular Tags |