?? bfishmod.java
字號:
/** @(#)BFishMod.java version 1.0 Jeffrey M Wheaton */ /* * Copyright (C) 2002 Jeffrey M Wheaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */import java.io.*;import java.util.*;/**This is the module for the Blowfish encryption algorithm.@author Jeffrey M Wheaton@version version 1.0*/public final class BFishMod implements CryptInterface{ private byte[] key; private int[] pbox, sbox1, sbox2, sbox3, sbox4; /**The default constructor simply initializes the array values to the initial values required for the algorithm. This will hopefully save time when this module is loaded. */ public BFishMod(){ pbox = new int[PBOX_SIZE]; sbox1 = new int[SBOX_SIZE]; sbox2 = new int[SBOX_SIZE]; sbox3 = new int[SBOX_SIZE]; sbox4 = new int[SBOX_SIZE]; int i; for(i = 0; i < PBOX_SIZE; i++){ pbox[i] = pbox_init[i]; } for(i = 0; i < SBOX_SIZE; i++){ sbox1[i] = sbox_init_1[i]; sbox2[i] = sbox_init_2[i]; sbox3[i] = sbox_init_3[i]; sbox4[i] = sbox_init_4[i]; } } //this method initializes the arrays and prepares for encryption/decryption private void init(){ int i; int keyCount = 0; int keyBuild = 0; for(i = 0; i < PBOX_SIZE; i++){ for(int j = 0; j < 4; j++){ keyBuild = (keyBuild << 8) | (((int)key[keyCount]) & 0x0ff); if(++keyCount == key.length) keyCount = 0; } pbox[i] = pbox[i] ^ keyBuild; } //sbox initialization long zeroString = 0; for(i = 0; i < PBOX_SIZE; i = i + 2){ zeroString = encryptBlock(zeroString); pbox[i] = (int)(zeroString >>> 32); pbox[i + 1] = (int)(zeroString & 0x0ffffffffL); } for(i = 0; i < SBOX_SIZE; i = i + 2){ zeroString = encryptBlock(zeroString); sbox1[i] = (int)(zeroString >>> 32); sbox1[i + 1] = (int)(zeroString & 0x0ffffffffL); } for(i = 0; i < SBOX_SIZE; i = i + 2){ zeroString = encryptBlock(zeroString); sbox2[i] = (int)(zeroString >>> 32); sbox2[i + 1] = (int)(zeroString & 0x0ffffffffL); } for(i = 0; i < SBOX_SIZE; i = i + 2){ zeroString = encryptBlock(zeroString); sbox3[i] = (int)(zeroString >>> 32); sbox3[i + 1] = (int)(zeroString & 0x0ffffffffL); } for(i = 0; i < SBOX_SIZE; i = i + 2){ zeroString = encryptBlock(zeroString); sbox4[i] = (int)(zeroString >>> 32); sbox4[i + 1] = (int)(zeroString & 0x0ffffffffL); } } //this method encrypts one 64 bit block private long encryptBlock(long block){ int xL = getHiOrder(block); int xR = getLoOrder(block); int temp = 0; for(int i = 0; i < 16; i++){ xL = xL ^ pbox[i]; xR ^= ((sbox1[xL >>> 24] + sbox2[((xL >>> 16) & 0x0ff)]) ^ sbox3[((xL >>> 8) & 0x0ff)]) + sbox4[(xL & 0x0ff)]; temp = xL; xL = xR; xR = temp; } temp = xL; xL = xR; xR = temp; xR ^= pbox[16]; xL ^= pbox[17]; return glueInts(xL, xR); } //this method converts a portion of a byte array to a long private static long byteToLong(byte[] b, int off){ long newLong = 0; int shift = 56; for(int i = off; i < off + BLOCK_SIZE; i++){ try{ newLong = newLong | (((long)b[i] & 0x0ffL) << shift); shift = shift - BLOCK_SIZE; } catch(ArrayIndexOutOfBoundsException e){ return newLong; } } return newLong; } //this method stores a long value into a byte array at a certain offset private static void longToByte(long block, byte[] b, int off){ int shift = 56; for(int i = off; i < off + BLOCK_SIZE; i++){ try{ b[i] = (byte)((block >>> shift) & 0x0ff); shift = shift - BLOCK_SIZE; } catch(ArrayIndexOutOfBoundsException aie){ return; //this shouldn't be needed with proper error checking } } } //this method puts together two ints private static long glueInts(int left, int right){ return ((((long)left) << 32) | ((long)right & 0x00000000ffffffffL)); } //this method gets the high order bits (left) of the long private static int getHiOrder(long val){ return (int)((long)(val >>> 32)); } //this method gets the low order bits (right) of the long private static int getLoOrder(long val){ return (int)val; } //this method tests the key length private boolean testKey(byte[] b){ if(b.length < MIN_KEY_LENGTH || b.length > MAX_KEY_LENGTH) return false; return true; } //this method encrypts a single byte array // __TODO__ CHECK LOGIC private byte[] encrypt(byte[] b){ byte[] a = new byte[b.length]; for(int i = 0; i < b.length; i = i + BLOCK_SIZE){ long block = byteToLong(b, i); block = encryptBlock(block); longToByte(block, a, i); } return a; } //this method is used to decrypt a long value private long decryptBlock(long block){ int xL = getHiOrder(block); int xR = getLoOrder(block); int temp = 0; for(int i = 17; i > 1; i--){ xL ^= pbox[i]; xR ^= ((sbox1[(xL >>> 24)] + sbox2[((xL >>> 16) & 0x0ff)]) ^ sbox3[((xL >>> 8) & 0x0ff)]) + sbox4[(xL & 0x0ff)]; temp = xL; xL = xR; xR = temp; } temp = xL; xL = xR; xR = temp; xR ^= pbox[1]; xL ^= pbox[0]; return glueInts(xL, xR); } //this method is used to decrypt a byte array // __TODO__ CHECK THIS FOR LOGIC MAINLY THE FOR LOOP INVARIANT private byte[] decryptByte(byte[] file, int fileSize){ long temp = 0; long done = 0; byte[] newFile = new byte[fileSize]; // __TODO__ REMOVE THESE COMMENTED LINES IF THE TESTING PASSES //THIS WAS THE OLD VERSION (8 - (file.length%8)) SHOULD BE ZERO EVERY TIME for(int i = 0; i < file.length + (8 - ((file.length)%8)); i = i + BLOCK_SIZE){ temp = byteToLong(file, i); done = decryptBlock(temp); longToByte(done, newFile, i); } return newFile; } /*******************************************************************/ /**This method is implemented from the CryptInterface class. It simply encrypts the file (java class) and overwrites the existing version. So if you plan on using this class make sure you make a copy of your originals, if you do not wish to recompile. @param File file - the file to encrypt. @return returns the file after it has been encrypted. */ public File encrypt(File file){ File newFile = null; try{ FileInputStream f = new FileInputStream(file); int fileSize = f.available(); byte[] b = new byte[(fileSize) + (8 - (fileSize%8))]; //this guarantees new file is divisible by 8 f.read(b, 0, fileSize); f.close(); newFile = new File(file.getAbsolutePath()); FileOutputStream of = new FileOutputStream(newFile); //write the file size to the front of the file of.write(((fileSize >>> 24) & 0x0ff)); of.write(((fileSize >>> 16) & 0x0ff)); of.write(((fileSize >>> 8) & 0x0ff)); of.write((fileSize & 0x0ff)); //encrypt of.write(encrypt(b)); of.flush(); of.close(); } catch(IOException ioe){ ioe.printStackTrace(); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -