📄 des.java
字号:
0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; private static final int[] SP8 = new int[] { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; /** * Constants that help in determining whether or not a byte array is parity * adjusted. */ private static final byte[] PARITY = { 8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 3, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, 8, 5, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 6, 8 }; // Key schedule constants. private static final byte[] ROTARS = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; private static final byte[] PC1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; private static final byte[] PC2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; /** * Weak keys (parity adjusted): If all the bits in each half are either 0 * or 1, then the key used for any cycle of the algorithm is the same as * all other cycles. */ public static final byte[][] WEAK_KEYS = { Util.toBytesFromString("0101010101010101"), Util.toBytesFromString("01010101FEFEFEFE"), Util.toBytesFromString("FEFEFEFE01010101"), Util.toBytesFromString("FEFEFEFEFEFEFEFE") }; /** * Semi-weak keys (parity adjusted): Some pairs of keys encrypt plain text * to identical cipher text. In other words, one key in the pair can decrypt * messages that were encrypted with the other key. These keys are called * semi-weak keys. This occurs because instead of 16 different sub-keys being * generated, these semi-weak keys produce only two different sub-keys. */ public static final byte[][] SEMIWEAK_KEYS = { Util.toBytesFromString("01FE01FE01FE01FE"), Util.toBytesFromString("FE01FE01FE01FE01"), Util.toBytesFromString("1FE01FE00EF10EF1"), Util.toBytesFromString("E01FE01FF10EF10E"), Util.toBytesFromString("01E001E001F101F1"), Util.toBytesFromString("E001E001F101F101"), Util.toBytesFromString("1FFE1FFE0EFE0EFE"), Util.toBytesFromString("FE1FFE1FFE0EFE0E"), Util.toBytesFromString("011F011F010E010E"), Util.toBytesFromString("1F011F010E010E01"), Util.toBytesFromString("E0FEE0FEF1FEF1FE"), Util.toBytesFromString("FEE0FEE0FEF1FEF1") }; /** Possible weak keys (parity adjusted) --produce 4 instead of 16 subkeys. */ public static final byte[][] POSSIBLE_WEAK_KEYS = { Util.toBytesFromString("1F1F01010E0E0101"), Util.toBytesFromString("011F1F01010E0E01"), Util.toBytesFromString("1F01011F0E01010E"), Util.toBytesFromString("01011F1F01010E0E"), Util.toBytesFromString("E0E00101F1F10101"), Util.toBytesFromString("FEFE0101FEFE0101"), Util.toBytesFromString("FEE01F01FEF10E01"), Util.toBytesFromString("E0FE1F01F1FE0E01"), Util.toBytesFromString("FEE0011FFEF1010E"), Util.toBytesFromString("E0FE011FF1FE010E"), Util.toBytesFromString("E0E01F1FF1F10E0E"), Util.toBytesFromString("FEFE1F1FFEFE0E0E"), Util.toBytesFromString("1F1F01010E0E0101"), Util.toBytesFromString("011F1F01010E0E01"), Util.toBytesFromString("1F01011F0E01010E"), Util.toBytesFromString("01011F1F01010E0E"), Util.toBytesFromString("01E0E00101F1F101"), Util.toBytesFromString("1FFEE0010EFEF001"), Util.toBytesFromString("1FE0FE010EF1FE01"), Util.toBytesFromString("01FEFE0101FEFE01"), Util.toBytesFromString("1FE0E01F0EF1F10E"), Util.toBytesFromString("01FEE01F01FEF10E"), Util.toBytesFromString("01E0FE1F01F1FE0E"), Util.toBytesFromString("1FFEFE1F0EFEFE0E"), Util.toBytesFromString("E00101E0F10101F1"), Util.toBytesFromString("FE1F01E0FE0E0EF1"), Util.toBytesFromString("FE011FE0FE010EF1"), Util.toBytesFromString("E01F1FE0F10E0EF1"), Util.toBytesFromString("FE0101FEFE0101FE"), Util.toBytesFromString("E01F01FEF10E01FE"), Util.toBytesFromString("E0011FFEF1010EFE"), Util.toBytesFromString("FE1F1FFEFE0E0EFE"), Util.toBytesFromString("1FFE01E00EFE01F1"), Util.toBytesFromString("01FE1FE001FE0EF1"), Util.toBytesFromString("1FE001FE0EF101FE"), Util.toBytesFromString("01E01FFE01F10EFE"), Util.toBytesFromString("0101E0E00101F1F1"), Util.toBytesFromString("1F1FE0E00E0EF1F1"), Util.toBytesFromString("1F01FEE00E01FEF1"), Util.toBytesFromString("011FFEE0010EFEF1"), Util.toBytesFromString("1F01E0FE0E01F1FE"), Util.toBytesFromString("011FE0FE010EF1FE"), Util.toBytesFromString("0101FEFE0001FEFE"), Util.toBytesFromString("1F1FFEFE0E0EFEFE"), Util.toBytesFromString("FEFEE0E0FEFEF1F1"), Util.toBytesFromString("E0FEFEE0F1FEFEF1"), Util.toBytesFromString("FEE0E0FEFEF1F1FE"), Util.toBytesFromString("E0E0FEFEF1F1FEFE") }; // Constructor(s) // ------------------------------------------------------------------------- /** Default 0-argument constructor. */ public DES() { super(Registry.DES_CIPHER, BLOCK_SIZE, KEY_SIZE); } // Class methods // ------------------------------------------------------------------------- /** * <p>Adjust the parity for a raw key array. This essentially means that each * byte in the array will have an odd number of '1' bits (the last bit in * each byte is unused.</p> * * @param kb The key array, to be parity-adjusted. * @param offset The starting index into the key bytes. */ public static void adjustParity(byte[] kb, int offset) { for (int i = offset; i < KEY_SIZE; i++) { kb[i] ^= (PARITY[kb[i] & 0xff] == 8) ? 1 : 0; } } /** * <p>Test if a byte array, which must be at least 8 bytes long, is parity * adjusted.</p> * * @param kb The key bytes. * @param offset The starting index into the key bytes. * @return <code>true</code> if the first 8 bytes of <i>kb</i> have been * parity adjusted. <code>false</code> otherwise. */ public static boolean isParityAdjusted(byte[] kb, int offset) { int w = 0x88888888; int n = PARITY[kb[offset + 0] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 1] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 2] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 3] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 4] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 5] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 6] & 0xff]; n <<= 4; n |= PARITY[kb[offset + 7] & 0xff]; return (n & w) == 0; } /** * <p>Test if a key is a weak key.</p> * * @param kb The key to test. * @return <code>true</code> if the key is weak. */ public static boolean isWeak(byte[] kb) { // return Arrays.equals(kb, WEAK_KEYS[0]) || Arrays.equals(kb, WEAK_KEYS[1]) // || Arrays.equals(kb, WEAK_KEYS[2]) || Arrays.equals(kb, WEAK_KEYS[3]) // || Arrays.equals(kb, WEAK_KEYS[4]) || Arrays.equals(kb, WEAK_KEYS[5]) // || Arrays.equals(kb, WEAK_KEYS[6]) || Arrays.equals(kb, WEAK_KEYS[7]); for (int i = 0; i < WEAK_KEYS.length; i++) { if (Arrays.equals(WEAK_KEYS[i], kb)) { return true; } } return false; } /** * <p>Test if a key is a semi-weak key.</p> * * @param kb The key to test. * @return <code>true</code> if this key is semi-weak. */ public static boolean isSemiWeak(byte[] kb) { // return Arrays.equals(kb, SEMIWEAK_KEYS[0]) // || Arrays.equals(kb, SEMIWEAK_KEYS[1]) // || Arrays.equals(kb, SEMIWEAK_KEYS[2]) // || Arrays.equals(kb, SEMIWEAK_KEYS[3]) // || Arrays.equals(kb, SEMIWEAK_KEYS[4]) // || Arrays.equals(kb, SEMIWEAK_KEYS[5]) // || Arrays.equals(kb, SEMIWEAK_KEYS[6]) // || Arrays.equals(kb, SEMIWEAK_KEYS[7]) // || Arrays.equals(kb, SEMIWEAK_KEYS[8]) // || Arrays.equals(kb, SEMIWEAK_KEYS[9]) // || Arrays.equals(kb, SEMIWEAK_KEYS[10]) // || Arrays.equals(kb, SEMIWEAK_KEYS[11]); for (int i = 0; i < SEMIWEAK_KEYS.length; i++) { if (Arrays.equals(SEMIWEAK_KEYS[i], kb)) { return true; } } return false; } /** * <p>Test if the designated byte array represents a possibly weak key.</p> * * @param kb the byte array to test. * @return <code>true</code> if <code>kb</code>represents a possibly weak key. * Returns <code>false</code> otherwise. */ public static boolean isPossibleWeak(byte[] kb) { for (int i = 0; i < POSSIBLE_WEAK_KEYS.length; i++) { if (Arrays.equals(POSSIBLE_WEAK_KEYS[i], kb)) { return true; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -