📄 des.java
字号:
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 [] ti = new int [2]; ti[0] = v0; ti[1] = v1; int [] ref_to_d01 = new int[2]; while( length-- > 0) { des_encrypt(ti, Des.ENCRYPT); /* c2ln(in,d0,d1,n); */ Int32Manipulator.c2ln(input, input_start, n, ref_to_d01); 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; } v0 = ti[0]; v1 = ti[1]; Int32Manipulator.set_int( ivec, 0, v0); Int32Manipulator.set_int( ivec, 4, v1); } /** * Do the CFB mode with 64 bit feedback. Used to encrypt/decrypt * arbitrary numbers of bytes. To use this initialize num[0] to zero * and set input_start to the correct offset into input, and length to * the number of bytes following that offset that you wish to encrypt * before calling. * * @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 num Reference to an int used to keep track of 'how far' we are though ivec. Updated on exit. * @param encrypt Pass Des.ENCRYPT to encrypt, Des.DECRYPT to * decrypt. */ public void cfb64_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, byte [] ivec, int [] num, boolean encrypt) { byte c; byte cc; int n = num[0]; int [] ti = new int [2]; if( encrypt == Des.ENCRYPT) { /* * Encrypt. */ while ((length--) != 0) { if (n == 0) { ti[0] = Int32Manipulator.bytes_to_int(ivec, 0); ti[1] = Int32Manipulator.bytes_to_int(ivec, 4); des_encrypt(ti, encrypt); Int32Manipulator.set_int(ivec, 0, ti[0]); Int32Manipulator.set_int(ivec, 4, ti[1]); } c = (byte)(input[input_start] ^ ivec[n]); output[output_start] = c; input_start++; output_start++; ivec[n] = c; n = (n + 1) & 0x7; } } else { /* * Decrypt. */ while ((length--) != 0) { if (n == 0) { ti[0] = Int32Manipulator.bytes_to_int(ivec, 0); ti[1] = Int32Manipulator.bytes_to_int(ivec, 4); des_encrypt(ti, Des.ENCRYPT); Int32Manipulator.set_int(ivec, 0, ti[0]); Int32Manipulator.set_int(ivec, 4, ti[1]); } cc = input[input_start]; c = ivec[n]; ivec[n] = cc; output[output_start] = (byte)(c ^ cc); input_start++; output_start++; n = (n + 1) & 0x7; } } num[0] = n; } /** * Do the OFB mode with 64 bit feedback. Used to encrypt/decrypt * arbitrary numbers of bytes. To use this initialize num[0] to zero * and set input_start to the correct offset into input, and length to * the number of bytes following that offset that you wish to encrypt * before calling. * * @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 num Reference to an int used to keep track of 'how far' we are though ivec. Updated on exit. */ public void ofb64_encrypt(byte [] input, int input_start, int length, byte [] output, int output_start, byte [] ivec, int [] num) { byte [] dp = new byte [8]; int [] ti = new int [2]; int n = num[0]; boolean save = false; ti[0] = Int32Manipulator.bytes_to_int(ivec, 0); ti[1] = Int32Manipulator.bytes_to_int(ivec, 4); Int32Manipulator.set_int(dp, 0, ti[0]); Int32Manipulator.set_int(dp, 4, ti[1]); while((length--) != 0) { if (n == 0) { des_encrypt(ti,Des.ENCRYPT); Int32Manipulator.set_int(dp, 0, ti[0]); Int32Manipulator.set_int(dp, 4, ti[1]); save = true; } output[output_start] = (byte)(input[input_start] ^ dp[n]); input_start++; output_start++; n = (n + 1) & 0x7; } if (save) { Int32Manipulator.set_int(ivec, 0, ti[0]); Int32Manipulator.set_int(ivec, 4, ti[1]); } num[0] = n; } /** * This function produces an 8 byte checksum from input that it puts in * output and returns the last 4 bytes as an int. The checksum is * generated via cbc mode of DES in which only the last 8 byes are * kept. I would recommend not using this function but instead using * the EVP_Digest routines, or at least using MD5 or SHA. This * function is used by Kerberos v4 so that is why it stays in the * library. * * @param input byte [] array to checksum. * @param input_start Offset into input array to begin. * @param length Number of bytes to process. * @param output byte [] array to write into. * @param output_start Offset into output to write into. * @param ivec Initialization vector. Not modified. */ public int cbc_cksum(byte [] input, int input_start, int length, byte [] output, int output_start, byte [] ivec) { int tin0; int tin1; int [] inout = new int [2]; int tout0 = Int32Manipulator.bytes_to_int(ivec, 0); int tout1 = Int32Manipulator.bytes_to_int(ivec, 4); int offset = 0; int chunksize; 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, Des.ENCRYPT); /* fix 15/10/91 eay - thanks to keithr@sco.COM */ tout0 = inout[0]; tout1 = inout[1]; input_start += chunksize; } Int32Manipulator.set_int(output, output_start, tout0); Int32Manipulator.set_int(output, output_start+4, tout1); return tout1; }}/** * TripleDes class. Does all modes of TripleDes encryption. * Written by Jeremy Allison (jra@cygnus.com) based on * C code from Eric Young (eay@mincom.oz.au). */class TripleDes implements DesCrypt { /** * Constant. Pass this to functions that have a boolean * encrypt parameter to tell them to encrypt the data. */ public static final boolean ENCRYPT = true; /** * Constant. Pass this to functions that have a boolean * encrypt parameter to tell them to decrypt the data. */ public static final boolean DECRYPT = false; private DesKey ks1_; private DesKey ks2_; private DesKey ks3_; /** * TripleDes constructor. Takes two DesKey objects. The first * key is used as the third key internally. Does not check * either key for parity or weakness. * * @param key1 First (and third) key * @param key2 Second key. */ public TripleDes(DesKey key1, DesKey key2) { ks1_ = key1; ks2_ = key2; ks3_ = ks1_; } /** * TripleDes constructor. Takes three DesKey objects. * Does not check keys for parity or weakness. * * @param key1 First key. * @param key2 Second key. * @param key3 Third key. */ public TripleDes(DesKey key1, DesKey key2, DesKey key3) { ks1_ = key1; ks2_ = key2; ks3_ = key3; } /** * Do the ecb (Encrypt/Decrypt 8 bytes electronic code book) * mode. Encrypts 8 bytes starting at offset input_start in * 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 [] ref_to_ll = new int [2]; int [] ref_to_l0 = new int [1]; int [] ref_to_l1 = new int [1]; ref_to_l0[0] = Int32Manipulator.bytes_to_int(input, input_start); ref_to_l1[0] = Int32Manipulator.bytes_to_int(input, input_start+4); Des des1 = new Des(ks1_); Des des2 = new Des(ks2_); Des des3 = new Des(ks3_); des1.IP(ref_to_l0, ref_to_l1); ref_to_ll[0] = ref_to_l0[0]; ref_to_ll[1] = ref_to_l1[0]; des1.des_encrypt2(ref_to_ll, encrypt); des2.des_encrypt2(ref_to_ll, !encrypt); des3.des_encrypt2(ref_to_ll, encrypt); ref_to_l0[0] = ref_to_ll[0]; ref_to_l1[0] = ref_to_ll[1]; des1.FP(ref_to_l1, ref_to_l0); Int32Manipulator.set_int(output, output_start, ref_to_l0[0]); Int32Manipulator.set_int(output, output_start+4, ref_to_l1[0]); } /** * 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 [] ref_to_tin0 = new int [1]; int [] ref_to_tin1 = new int [1]; int [] inout = new int[2]; int [] ref_to_tout0 = new int [1]; int [] ref_to_tout1 = new int [1]; int chunksize; Des des1 = new Des(ks1_); Des des2 = new Des(ks2_); Des des3 = new Des(ks3_); if(encrypt == TripleDes.ENCRYPT) { /* * Encrypt. */ ref_to_tout0[0] = Int32Manipulator.bytes_to_int(ivec,0); ref_to_tout1[0] = 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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -