📄 des.java
字号:
return false; } /** * <p>The core DES function. This is used for both encryption and decryption, * the only difference being the key.</p> * * @param in The input bytes. * @param i The starting offset into the input bytes. * @param out The output bytes. * @param o The starting offset into the output bytes. * @param key The working key. */ private static void desFunc(byte[] in, int i, byte[] out, int o, int[] key) { int right, left, work; // Load. left = (in[i++] & 0xff) << 24 | (in[i++] & 0xff) << 16 | (in[i++] & 0xff) << 8 | in[i++] & 0xff; right = (in[i++] & 0xff) << 24 | (in[i++] & 0xff) << 16 | (in[i++] & 0xff) << 8 | in[i] & 0xff; // Initial permutation. work = ((left >>> 4) ^ right) & 0x0F0F0F0F; left ^= work << 4; right ^= work; work = ((left >>> 16) ^ right) & 0x0000FFFF; left ^= work << 16; right ^= work; work = ((right >>> 2) ^ left) & 0x33333333; right ^= work << 2; left ^= work; work = ((right >>> 8) ^ left) & 0x00FF00FF; right ^= work << 8; left ^= work; right = ((right << 1) | ((right >>> 31) & 1)) & 0xFFFFFFFF; work = (left ^ right) & 0xAAAAAAAA; left ^= work; right ^= work; left = ((left << 1) | ((left >>> 31) & 1)) & 0xFFFFFFFF; int k = 0, t; for (int round = 0; round < 8; round++) { work = right >>> 4 | right << 28; work ^= key[k++]; t = SP7[work & 0x3F]; work >>>= 8; t |= SP5[work & 0x3F]; work >>>= 8; t |= SP3[work & 0x3F]; work >>>= 8; t |= SP1[work & 0x3F]; work = right ^ key[k++]; t |= SP8[work & 0x3F]; work >>>= 8; t |= SP6[work & 0x3F]; work >>>= 8; t |= SP4[work & 0x3F]; work >>>= 8; t |= SP2[work & 0x3F]; left ^= t; work = left >>> 4 | left << 28; work ^= key[k++]; t = SP7[work & 0x3F]; work >>>= 8; t |= SP5[work & 0x3F]; work >>>= 8; t |= SP3[work & 0x3F]; work >>>= 8; t |= SP1[work & 0x3F]; work = left ^ key[k++]; t |= SP8[work & 0x3F]; work >>>= 8; t |= SP6[work & 0x3F]; work >>>= 8; t |= SP4[work & 0x3F]; work >>>= 8; t |= SP2[work & 0x3F]; right ^= t; } // The final permutation. right = (right << 31) | (right >>> 1); work = (left ^ right) & 0xAAAAAAAA; left ^= work; right ^= work; left = (left << 31) | (left >>> 1); work = ((left >>> 8) ^ right) & 0x00FF00FF; left ^= work << 8; right ^= work; work = ((left >>> 2) ^ right) & 0x33333333; left ^= work << 2; right ^= work; work = ((right >>> 16) ^ left) & 0x0000FFFF; right ^= work << 16; left ^= work; work = ((right >>> 4) ^ left) & 0x0F0F0F0F; right ^= work << 4; left ^= work; out[o++] = (byte) (right >>> 24); out[o++] = (byte) (right >>> 16); out[o++] = (byte) (right >>> 8); out[o++] = (byte) right; out[o++] = (byte) (left >>> 24); out[o++] = (byte) (left >>> 16); out[o++] = (byte) (left >>> 8); out[o] = (byte) left; } // Instance methods implementing BaseCipher // ------------------------------------------------------------------------- public Object clone() { return new DES(); } public Iterator blockSizes() { return Collections.singleton(new Integer(BLOCK_SIZE)).iterator(); } public Iterator keySizes() { return Collections.singleton(new Integer(KEY_SIZE)).iterator(); } public Object makeKey(byte[] kb, int bs) throws InvalidKeyException { if (kb == null || kb.length != KEY_SIZE) throw new InvalidKeyException("DES keys must be 8 bytes long"); if (Properties.checkForWeakKeys() && (isWeak(kb) || isSemiWeak(kb) || isPossibleWeak(kb))) { throw new WeakKeyException(); } int i, j, l, m, n; long pc1m = 0, pcr = 0; for (i = 0; i < 56; i++) { l = PC1[i]; pc1m |= ((kb[l >>> 3] & (0x80 >>> (l & 7))) != 0) ? (1L << (55 - i)) : 0; } Context ctx = new Context(); // Encryption key first. for (i = 0; i < 16; i++) { pcr = 0; m = i << 1; n = m + 1; for (j = 0; j < 28; j++) { l = j + ROTARS[i]; if (l < 28) pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0; else pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j)) : 0; } for (j = 28; j < 56; j++) { l = j + ROTARS[i]; if (l < 56) pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0; else pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j)) : 0; } for (j = 0; j < 24; j++) { if ((pcr & 1L << (55 - PC2[j])) != 0) ctx.ek[m] |= 1 << (23 - j); if ((pcr & 1L << (55 - PC2[j + 24])) != 0) ctx.ek[n] |= 1 << (23 - j); } } // The decryption key is the same, but in reversed order. for (i = 0; i < Context.EXPANDED_KEY_SIZE; i += 2) { ctx.dk[30 - i] = ctx.ek[i]; ctx.dk[31 - i] = ctx.ek[i + 1]; } // "Cook" the keys. for (i = 0; i < 32; i += 2) { int x, y; x = ctx.ek[i]; y = ctx.ek[i + 1]; ctx.ek[i] = ((x & 0x00FC0000) << 6) | ((x & 0x00000FC0) << 10) | ((y & 0x00FC0000) >>> 10) | ((y & 0x00000FC0) >>> 6); ctx.ek[i + 1] = ((x & 0x0003F000) << 12) | ((x & 0x0000003F) << 16) | ((y & 0x0003F000) >>> 4) | (y & 0x0000003F); x = ctx.dk[i]; y = ctx.dk[i + 1]; ctx.dk[i] = ((x & 0x00FC0000) << 6) | ((x & 0x00000FC0) << 10) | ((y & 0x00FC0000) >>> 10) | ((y & 0x00000FC0) >>> 6); ctx.dk[i + 1] = ((x & 0x0003F000) << 12) | ((x & 0x0000003F) << 16) | ((y & 0x0003F000) >>> 4) | (y & 0x0000003F); } return ctx; } public void encrypt(byte[] in, int i, byte[] out, int o, Object K, int bs) { desFunc(in, i, out, o, ((Context) K).ek); } public void decrypt(byte[] in, int i, byte[] out, int o, Object K, int bs) { desFunc(in, i, out, o, ((Context) K).dk); } // Inner classe(s) // ========================================================================= /** * Simple wrapper class around the session keys. Package-private so TripleDES * can see it. */ final class Context { // Constants and variables // ---------------------------------------------------------------------- private static final int EXPANDED_KEY_SIZE = 32; /** The encryption key. */ int[] ek; /** The decryption key. */ int[] dk; // Constructor(s) // ---------------------------------------------------------------------- /** Default 0-arguments constructor. */ Context() { ek = new int[EXPANDED_KEY_SIZE]; dk = new int[EXPANDED_KEY_SIZE]; } // Class methods // ---------------------------------------------------------------------- // Instance methods // ---------------------------------------------------------------------- byte[] getEncryptionKeyBytes() { return toByteArray(ek); } byte[] getDecryptionKeyBytes() { return toByteArray(dk); } byte[] toByteArray(int[] k) { byte[] result = new byte[4 * k.length]; for (int i = 0, j = 0; i < k.length; i++) { result[j++] = (byte) (k[i] >>> 24); result[j++] = (byte) (k[i] >>> 16); result[j++] = (byte) (k[i] >>> 8); result[j++] = (byte) k[i]; } return result; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -