📄 des.java
字号:
* byte array input and writes them out at offset output_start in * byte array output. * * @param input Input byte [] array. * @param input_start Offset into input to start encryption. * @param output Output byte [] array. * @param output_start Offset into output to place result. * @param encrypt Pass Des.ENCRYPT to encrypt, Des.DECRYPT to * decrypt. * */ public void ecb_encrypt(byte [] input, int input_start, byte [] output, int output_start, boolean encrypt) { int [] ll = new int[2]; ll[0] = Int32Manipulator.bytes_to_int(input, input_start); ll[1] = Int32Manipulator.bytes_to_int(input, input_start+4); des_encrypt(ll, encrypt); Int32Manipulator.set_int(output, output_start, ll[0]); Int32Manipulator.set_int(output, output_start+4, ll[1]); } /** * Do the cbc (Cypher block chaining mode) * encrypt/decrypt. This updates the ivec array, and is equivalent * to the des_ncbc_encrypt in the C library. * * @param input Input byte [] array. * @param input_start Offset into input to start encryption. * @param length Number of bytes to encrypt. * @param output Output byte [] array. * @param output_start Offset into output to place result. * @param ivec Initialization vector. A byte [] array of length 8. Updated on exit. * @param encrypt Pass Des.ENCRYPT to encrypt, Des.DECRYPT to * decrypt. */ public void cbc_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, byte [] ivec, boolean encrypt) { int [] inout = new int[2]; int tin0; int tin1; int tout0; int tout1; int chunksize; if(encrypt == Des.ENCRYPT) { /* * Encrypt. */ tout0 = Int32Manipulator.bytes_to_int(ivec, 0); tout1 = Int32Manipulator.bytes_to_int(ivec, 4); /* * Deal with input 8 bytes at a time. */ for (; length > 0; length -=8) { if(length >= 8) { /* * We have a full 8 byte chunk. */ tin0 = Int32Manipulator.bytes_to_int(input, input_start); tin1 = Int32Manipulator.bytes_to_int(input, input_start+4); chunksize = 8; } else { /* * We only have a less than 8 byte fragment. */ int [] ref_to_tin01 = new int [2]; /* c2ln(in,tin0,tin1,length); */ chunksize = Int32Manipulator.c2ln(input, input_start, length, ref_to_tin01); tin0 = ref_to_tin01[0]; tin1 = ref_to_tin01[1]; } tin0 ^= tout0; tin1 ^= tout1; inout[0] = tin0; inout[1] = tin1; des_encrypt(inout, encrypt); tout0 = inout[0]; tout1 = inout[1]; Int32Manipulator.set_int(output, output_start, tout0); Int32Manipulator.set_int(output, output_start+4, tout1); input_start += chunksize; output_start += chunksize; } Int32Manipulator.set_int(ivec, 0, tout0); Int32Manipulator.set_int(ivec, 4, tout1); }else { /* * Decrypt. */ int xor0 = Int32Manipulator.bytes_to_int(ivec, 0); int xor1 = Int32Manipulator.bytes_to_int(ivec, 4); /* * Deal with input 8 bytes at a time. */ for (; length > 0; length -=8) { tin0 = Int32Manipulator.bytes_to_int(input, input_start); tin1 = Int32Manipulator.bytes_to_int(input, input_start+4); inout[0] = tin0; inout[1] = tin1; des_encrypt(inout, encrypt); tout0 = inout[0] ^ xor0; tout1 = inout[1] ^ xor1; if(length >= 8) { Int32Manipulator.set_int(output, output_start, tout0); Int32Manipulator.set_int(output, output_start+4, tout1); chunksize = 8; } else { chunksize = Int32Manipulator.l2cn(output, output_start, length, tout0, tout1); } xor0 = tin0; xor1 = tin1; input_start += chunksize; output_start += chunksize; } Int32Manipulator.set_int(ivec, 0, xor0); Int32Manipulator.set_int(ivec, 4, xor1); } } /** * This is Propagating Cipher Block Chaining mode of DES. It is used * by Kerberos v4. It's parameters are the same as cbc_encrypt(). * * @param input Input byte [] array. * @param input_start Offset into input to start encryption. * @param length Number of bytes to encrypt. * @param output Output byte [] array. * @param output_start Offset into output to place result. * @param ivec Initialization vector. A byte [] array of length 8. Updated on exit. * @param encrypt Pass Des.ENCRYPT to encrypt, Des.DECRYPT to * decrypt. */ public void pcbc_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, byte [] ivec, boolean encrypt) { int [] inout = new int[2]; int sin0; int sin1; int tout0; int tout1; int chunksize; int xor0 = Int32Manipulator.bytes_to_int(ivec, 0); int xor1 = Int32Manipulator.bytes_to_int(ivec, 4); if(encrypt == Des.ENCRYPT) { /* * Encrypt. */ /* * Deal with input 8 bytes at a time. */ for (; length > 0; length -=8) { if(length >= 8) { /* * We have a full 8 byte chunk. */ sin0 = Int32Manipulator.bytes_to_int(input, input_start); sin1 = Int32Manipulator.bytes_to_int(input, input_start+4); chunksize = 8; } else { /* * We only have a less than 8 byte fragment. */ int [] ref_to_sin01 = new int[2]; /* c2ln(in,sin0,sin1,length); */ chunksize = Int32Manipulator.c2ln(input,input_start, length,ref_to_sin01); sin0 = ref_to_sin01[0]; sin1 = ref_to_sin01[1]; } inout[0] = sin0^xor0; inout[1] = sin1^xor1; des_encrypt(inout, encrypt); tout0 = inout[0]; tout1 = inout[1]; xor0 = sin0^tout0; xor1 = sin1^tout1; Int32Manipulator.set_int(output, output_start, tout0); Int32Manipulator.set_int(output, output_start+4, tout1); input_start += chunksize; output_start += chunksize; } } else { /* * Decrypt. */ for (; length > 0; length -=8) { sin0 = Int32Manipulator.bytes_to_int(input, input_start); sin1 = Int32Manipulator.bytes_to_int(input, input_start+4); inout[0] = sin0; inout[1] = sin1; des_encrypt(inout, encrypt); tout0 = inout[0]^xor0; tout1 = inout[1]^xor1; if (length >= 8) { Int32Manipulator.set_int(output, output_start, tout0); Int32Manipulator.set_int(output, output_start+4, tout1); chunksize = 8; } else { chunksize = Int32Manipulator.l2cn(output, output_start, length, tout0, tout1); } xor0 = tout0^sin0; xor1 = tout1^sin1; input_start += chunksize; output_start += chunksize; } } } /** * Cipher Feedback Back mode of DES. This implementation 'feeds back' * in numbit blocks. The input (and output) is in multiples of numbits * bits. numbits should to be a multiple of 8 bits. Length is the * number of bytes input. If numbits is not a multiple of 8 bits, * the extra bits in the bytes will be considered padding. So if * numbits is 12, for each 2 input bytes, the 4 high bits of the * second byte will be ignored. So to encode 72 bits when using * a numbits of 12 take 12 bytes. To encode 72 bits when using * numbits of 9 will take 16 bytes. To encode 80 bits when using * numbits of 16 will take 10 bytes. etc, etc. This padding will * apply to both input and output. * * @param input Input byte [] array. * @param input_start Offset into input to start encryption. * @param length Number of bytes to encrypt. * @param output Output byte [] array. * @param output_start Offset into output to place result. * @param numbits Multiple of 8 bits as described above. * @param ivec Initialization vector. A byte [] array of length 8. Updated on exit. * @param encrypt Pass Des.ENCRYPT to encrypt, Des.DECRYPT to * decrypt. */ public void cfb_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, int numbits, byte [] ivec, boolean encrypt) { if(numbits > 64) numbits = 64; int n = (numbits+7)/8; int mask0; int mask1; if ( numbits > 32 ) { mask0 = 0xffffffff; if ( numbits == 64 ) { mask1 = mask0; } else { mask1 = (1<<(numbits-32))-1; } } else { if ( numbits == 32 ) { mask0 = 0xffffffff; } else { mask0 = (1<<numbits)-1; } mask1 = 0x00000000; } int v0 = Int32Manipulator.bytes_to_int(ivec, 0); int v1 = Int32Manipulator.bytes_to_int(ivec, 4); int [] ref_to_d01 = new int[2]; int [] ti = new int [2]; if(encrypt == Des.ENCRYPT) { /* * Encrypt. */ while( length >= n) { length -= n; ti[0] = v0; ti[1] = v1; des_encrypt(ti, encrypt); /* c2ln(in,d0,d1,n); */ Int32Manipulator.c2ln(input, input_start, n, ref_to_d01); input_start += n; ref_to_d01[0] = (ref_to_d01[0] ^ ti[0]) & mask0; ref_to_d01[1] = (ref_to_d01[1] ^ ti[1]) & mask1; /* l2cn(d0,d1,out,n); */ Int32Manipulator.l2cn(output, output_start, n, ref_to_d01[0], ref_to_d01[1]); output_start += n; if (numbits == 32){ v0 = v1; v1 = ref_to_d01[0]; } else if (numbits == 64) { v0 = ref_to_d01[0]; v1 = ref_to_d01[1]; } else if (numbits > 32) { /* && numbits != 64 */ v0 = ((v1>>>(numbits-32))|(ref_to_d01[0]<<(64-numbits))); v1 = ((ref_to_d01[0]>>>(numbits-32))|(ref_to_d01[1]<<(64-numbits))); } else {/* numbits < 32 */ v0 = ((v0>>>numbits)|(v1<<(32-numbits))); v1 = ((v1>>>numbits)|(ref_to_d01[0]<<(32-numbits))); } } } else { /* * Decrypt. */ while (length >= n) { length -= n; ti[0] = v0; ti[1] = v1; des_encrypt(ti, Des.ENCRYPT); /* c2ln(in,d0,d1,n); */ Int32Manipulator.c2ln(input, input_start, n, ref_to_d01); if (numbits == 32) { v0 = v1; v1 = ref_to_d01[0]; } else if (numbits == 64) { v0 = ref_to_d01[0]; v1 = ref_to_d01[1]; } else if (numbits > 32) { /* && numbits != 64 */ v0 = ((v1>>>(numbits-32))|(ref_to_d01[0]<<(64-numbits))); v1 = ((ref_to_d01[0]>>>(numbits-32))|(ref_to_d01[1]<<(64-numbits))); } else { /* numbits < 32 */ v0 = ((v0>>>numbits)|(v1<<(32-numbits))); v1 = ((v1>>>numbits)|(ref_to_d01[0]<<(32-numbits))); } ref_to_d01[0] = (ref_to_d01[0] ^ ti[0]) & mask0; ref_to_d01[1] = (ref_to_d01[1] ^ ti[1]) & mask1; /* l2cn(d0,d1,out,n); */ Int32Manipulator.l2cn(output, output_start, n, ref_to_d01[0], ref_to_d01[1]); input_start += n; output_start += n; } } Int32Manipulator.set_int( ivec, 0, v0); Int32Manipulator.set_int( ivec, 4, v1); } /** * This is a implementation of Output Feed Back mode of DES. It is * the same as cfb_encrypt() in that numbits is the size of the * units dealt with during input and output (in bits). * * @param input Input byte [] array. * @param input_start Offset into input to start encryption. * @param length Number of bytes to encrypt. * @param output Output byte [] array. * @param output_start Offset into output to place result. * @param numbits Multiple of 8 bits as described above. * @param ivec Initialization vector. A byte [] array of length 8. Updated on exit. */ public void ofb_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, int numbits, byte [] ivec) { if(numbits > 64) numbits = 64; int n = (numbits+7)/8; int mask0; int mask1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -