📄 blowfish.java
字号:
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. * * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE. If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************//* * Author's comment: The contents of this file is heavily based upon Bruce * Schneier's (who is the inventor of the algorithm) c-code found in his book: * Bruce Schneier: Applied Cryptography 2nd ed., John Wiley & Sons, 1996 */package com.mindbright.security.cipher;import com.mindbright.jca.security.InvalidKeyException;public final class Blowfish extends BlockCipher { private final static int BLOCK_SIZE = 8; // bytes in a data-block protected int[] S0 = new int[256]; protected int[] S1 = new int[256]; protected int[] S2 = new int[256]; protected int[] S3 = new int[256]; protected int[] P = new int[18]; public Blowfish() { S0 = new int[256]; S1 = new int[256]; S2 = new int[256]; S3 = new int[256]; P = new int[18]; } public int getBlockSize() { return BLOCK_SIZE; } public synchronized void initializeKey(byte[] key) throws InvalidKeyException { int i, j, len = key.length; int temp; System.arraycopy(blowfish_pbox, 0, P, 0, 18); System.arraycopy(blowfish_sbox, 0, S0, 0, 256); System.arraycopy(blowfish_sbox, 256, S1, 0, 256); System.arraycopy(blowfish_sbox, 512, S2, 0, 256); System.arraycopy(blowfish_sbox, 768, S3, 0, 256); // Actual subkey generation // for(j = 0, i = 0; i < 16 + 2; i++) { temp = (( (key[j] & 0xff) << 24) | ( (key[(j + 1) % len] & 0xff) << 16) | ( (key[(j + 2) % len] & 0xff) << 8) | ( (key[(j + 3) % len] & 0xff))); P[i] = P[i] ^ temp; j = (j + 4) % len; } byte[] LR = new byte[8]; for(i = 0; i < 16 + 2; i += 2) { blockEncrypt(LR, 0, LR, 0); P[i] = getIntMSBO(LR, 0); P[i + 1] = getIntMSBO(LR, 4); } for(j = 0; j < 256; j += 2) { blockEncrypt(LR, 0, LR, 0); S0[j] = getIntMSBO(LR, 0); S0[j + 1] = getIntMSBO(LR, 4); } for(j = 0; j < 256; j += 2) { blockEncrypt(LR, 0, LR, 0); S1[j] = getIntMSBO(LR, 0); S1[j + 1] = getIntMSBO(LR, 4); } for(j = 0; j < 256; j += 2) { blockEncrypt(LR, 0, LR, 0); S2[j] = getIntMSBO(LR, 0); S2[j + 1] = getIntMSBO(LR, 4); } for(j = 0; j < 256; j += 2) { blockEncrypt(LR, 0, LR, 0); S3[j] = getIntMSBO(LR, 0); S3[j + 1] = getIntMSBO(LR, 4); } } public void blockEncrypt(byte[] in, int inOffset, byte[] out, int outOffset) { int L, R; L = getIntMSBO(in, inOffset); R = getIntMSBO(in, inOffset + 4); L ^= P[0]; R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[1]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[2]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[3]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[4]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[5]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[6]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[7]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[8]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[9]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[10]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[11]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[12]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[13]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[14]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[15]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[16]); R ^= P[17]; putIntMSBO(R, out, outOffset); putIntMSBO(L, out, outOffset + 4); } public void blockDecrypt(byte[] in, int inOffset, byte[] out, int outOffset) { int L, R; L = getIntMSBO(in, inOffset); R = getIntMSBO(in, inOffset + 4); L ^= P[17]; R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[16]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[15]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[14]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[13]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[12]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[11]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[10]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[9]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[8]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[7]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[6]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[5]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[4]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[3]); R ^= ((((S0[(int)((L >>> 24) & 0xff)] + S1[(int)((L >>> 16) & 0xff)]) ^ S2[(int)((L >>> 8) & 0xff)]) + S3[(int)(L & 0xff)]) ^ P[2]); L ^= ((((S0[(int)((R >>> 24) & 0xff)] + S1[(int)((R >>> 16) & 0xff)]) ^ S2[(int)((R >>> 8) & 0xff)]) + S3[(int)(R & 0xff)]) ^ P[1]); R ^= P[0]; putIntMSBO(R, out, outOffset); putIntMSBO(L, out, outOffset + 4); } /* Blowfish's P and S -boxes, respectively. These were taken from Bruce Schneier's public-domain implementation. */ final static int[] blowfish_pbox = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b }; final static int[] blowfish_sbox = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -