?? blowfishcipher.java
字號:
/* * File: BlowfishCipher.java * * The Blowfish symmetric encryption algorithm, created by Bruce Schneier. * 64-bit (8 byte) block cipher. * Does not work (not tested) on message sizes over 2 billion bits long. * * version 1.02 v1a * Copyright 1998, 1999 by Hush Communications Corporation, BWI */package hushcode;import java.util.Random;final class BlowfishCipher{ private int[] S0 = new int[256], S1 = new int[256], S2 = new int[256], S3 = new int[256], P = new int[18]; private int P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17; BlowfishCipher() { } // Set key of this BlowfishCipher from a String void setKey(String skey) { byte[] key = new byte[skey.length()]; skey.getBytes(0, skey.length(), key, 0); setKey(key); } // Set key of this BlowfishCipher from a byte array void setKey(byte[] key) { int i, j, k, l, len = key.length; int[] Ptemp = {0, 0}; int[][] Stemp = {S0, S1, S2, S3}; System.arraycopy(Pinit, 0, P, 0, 18); for(i = 0, j = 0; j < 4; i += 256, j++) System.arraycopy(Sinit, i, Stemp[j], 0, 256); // Generate the P-values for this key for (i = 0, j = 0, l = 0; i < 18; P[i++] ^= l) for (k = 0; k < 4; k++, j++) l = (l << 8) | (key[j %= len] & 0xff); encrypt(Ptemp, 0, P, 0); for (i = 0; i < 16; i += 2) encrypt(P, i, P, i + 2); // Get rid of the slow P-array (ugly, but faster).. P0 = P[ 0]; P1 = P[ 1]; P2 = P[ 2]; P3 = P[ 3]; P4 = P[ 4]; P5 = P[ 5]; P6 = P[ 6]; P7 = P[ 7]; P8 = P[ 8]; P9 = P[ 9]; P10 = P[10]; P11 = P[11]; P12 = P[12]; P13 = P[13]; P14 = P[14]; P15 = P[15]; P16 = P[16]; P17 = P[17]; // Generate the final S-values S0[0] = P16; S0[1] = P17; k = 0; l = 0; for(i = 0; i < 4; i++) for (j = 0; j < 256; k = i, l = j, j += 2) encrypt(Stemp[k], l, Stemp[i], j); } // Encrypt two integers, not optimized, used by the setKey() method. private void encrypt(int in[], int inOff, int[] out, int outOff) { int L = in[inOff++] ^ P[0], R = in[inOff], i = 0; while(i < 16) { R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P[++i]; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P[++i]; } out[outOff++] = R ^ P[17]; out[outOff ] = L; } /** * This method accepts a string and returns an array * of bytes encrypted by CBC Blowfish. */ byte[] stringEncrypt(String inString) { byte[] returnBytes = encrypt(inString.getBytes()); return returnBytes; } /** * This method accepts a byte array and returns an array * of bytes encrypted by CBC Blowfish. * * Pad using PK1 and leave space for the initializationi vector.??? */ byte[] encrypt(byte[] bytes) { int leftoverspace = 8 - (bytes.length%8); byte[] inBytes = new byte[bytes.length + leftoverspace + 8]; for (int n=bytes.length+8;n<bytes.length+leftoverspace+8;n++) inBytes[n]=(byte)leftoverspace; /* Set a 64 bit initialization vector */ Random rand = new Random(); byte[] iv = new byte[8]; rand.nextBytes(iv); System.arraycopy(iv, 0, inBytes, 0, 8); // Copy in plain text System.arraycopy(bytes, 0, inBytes, 8, bytes.length); /* encrypt * including CBC with initialization vector. * For no good reason we also encrypt the initialization vector */ byte[] outBytes = new byte[inBytes.length]; encrypt(inBytes, 0, outBytes, 0); for (int xx=8;xx<16;xx++) inBytes[xx]^=inBytes[xx-8]; encrypt(inBytes,8,outBytes,8); for (int x=16;x<inBytes.length;x=x+8) { for (int xx=0; xx<8; xx++) inBytes[x+xx] ^= outBytes[x+xx-8]; encrypt(inBytes, x, outBytes, x); } return outBytes; } /** * This method accepts an array of bytes * encrypted by CBC Blowfish and returns a string. */ String stringDecrypt(byte[] inBytes) { String outString = new String(decrypt(inBytes)); return outString; } /** * This method accepts an array of bytes * encrypted by CBC Blowfish and returns a string. */ byte[] decrypt(byte[] inBytes) { byte[] outBytes = new byte[inBytes.length]; decrypt(inBytes,0,outBytes,0); decrypt(inBytes,8,outBytes,8); for (int xx=0; xx<8; xx++) outBytes[8+xx]^=outBytes[xx]; for (int x=16; x<inBytes.length; x=x+8) { decrypt(inBytes,x,outBytes,x); for (int xx=0; xx<8; xx++) outBytes[x+xx] ^= inBytes[x+xx-8]; } // Remove padding and initialization vector; int leftoverspace = outBytes[outBytes.length-1]; byte[] bytes = new byte[outBytes.length-(leftoverspace+8)]; System.arraycopy(outBytes, 8, bytes, 0, bytes.length); return bytes; } // Encrypt a block of eight bytes as fast as possible .. void encrypt (byte[] in, int off, byte[] out, int outOff) { int L = (((in[off++] & 0xff) << 24) | ((in[off++] & 0xff) << 16) | ((in[off++] & 0xff) << 8) | (in[off++] & 0xff) ) ^ P0 , R = ((in[off++] & 0xff) << 24) | ((in[off++] & 0xff) << 16) | ((in[off++] & 0xff) << 8) | (in[off ] & 0xff); R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P1; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P2; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P3; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P4; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P5; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P6; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P7; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P8; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P9; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P10; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P11; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P12; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P13; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P14; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P15; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P16; R ^= P17; out[outOff++] = (byte)((R >>> 24) & 0xff); out[outOff++] = (byte)((R >>> 16) & 0xff); out[outOff++] = (byte)((R >>> 8) & 0xff); out[outOff++] = (byte)( R & 0xff); out[outOff++] = (byte)((L >>> 24) & 0xff); out[outOff++] = (byte)((L >>> 16) & 0xff); out[outOff++] = (byte)((L >>> 8) & 0xff); out[outOff ] = (byte)( L & 0xff); } // Decrypt a block of eight bytes void decrypt (byte[] in, int off, byte[] out, int outOff) { int L = (((in[off++] & 0xff) << 24) | ((in[off++] & 0xff) << 16) | ((in[off++] & 0xff) << 8) | (in[off++] & 0xff) ) ^ P17, R = ((in[off++] & 0xff) << 24) | ((in[off++] & 0xff) << 16) | ((in[off++] & 0xff) << 8) | (in[off ] & 0xff); R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P16; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P15; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P14; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P13; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P12; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P11; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P10; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P9; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P8; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P7; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P6; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P5; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P4; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P3; R ^= (((S0[(L>>>24)&0xff]+S1[(L>>>16)&0xff])^S2[(L>>>8)&0xff])+S3[L&0xff])^P2; L ^= (((S0[(R>>>24)&0xff]+S1[(R>>>16)&0xff])^S2[(R>>>8)&0xff])+S3[R&0xff])^P1; R ^= P0; out[outOff++] = (byte)((R >>> 24) & 0xff); out[outOff++] = (byte)((R >>> 16) & 0xff); out[outOff++] = (byte)((R >>> 8) & 0xff); out[outOff++] = (byte)( R & 0xff); out[outOff++] = (byte)((L >>> 24) & 0xff); out[outOff++] = (byte)((L >>> 16) & 0xff); out[outOff++] = (byte)((L >>> 8) & 0xff); out[outOff ] = (byte)( L & 0xff); } private static final int[] Pinit = {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -