001 package railo.runtime.crypt; 002 003 import java.security.MessageDigest; 004 import java.util.Random; 005 006 import railo.runtime.exp.ExceptionHandler; 007 008 009 /** 010 * implementation of the Blowfish encryption 011 */ 012 public final class Blowfish { 013 private static class BlowfishCBC extends BlowfishECB { 014 015 long m_lCBCIV; 016 017 public long getCBCIV() { 018 return m_lCBCIV; 019 } 020 021 public void getCBCIV(byte dest[]) { 022 Blowfish.longToByteArray(m_lCBCIV, dest, 0); 023 } 024 025 public void setCBCIV(long lNewCBCIV) { 026 m_lCBCIV = lNewCBCIV; 027 } 028 029 public void setCBCIV(byte newCBCIV[]) { 030 m_lCBCIV = Blowfish.byteArrayToLong(newCBCIV, 0); 031 } 032 033 public void cleanUp() { 034 m_lCBCIV = 0L; 035 super.cleanUp(); 036 } 037 038 private long encryptBlockCBC(long lPlainblock) { 039 lPlainblock ^= m_lCBCIV; 040 lPlainblock = super.encryptBlock(lPlainblock); 041 return m_lCBCIV = lPlainblock; 042 } 043 044 private long decryptBlockCBC(long lCipherblock) { 045 long lTemp = lCipherblock; 046 lCipherblock = super.decryptBlock(lCipherblock); 047 lCipherblock ^= m_lCBCIV; 048 m_lCBCIV = lTemp; 049 return lCipherblock; 050 } 051 052 public void encrypt(byte inbuffer[], byte outbuffer[]) { 053 int nLen = inbuffer.length; 054 for(int nI = 0; nI < nLen; nI += 8) { 055 long lTemp = Blowfish.byteArrayToLong(inbuffer, nI); 056 lTemp = encryptBlockCBC(lTemp); 057 Blowfish.longToByteArray(lTemp, outbuffer, nI); 058 } 059 060 } 061 062 public void encrypt(byte buffer[]) { 063 int nLen = buffer.length; 064 for(int nI = 0; nI < nLen; nI += 8) { 065 long lTemp = Blowfish.byteArrayToLong(buffer, nI); 066 lTemp = encryptBlockCBC(lTemp); 067 Blowfish.longToByteArray(lTemp, buffer, nI); 068 } 069 070 } 071 072 public void encrypt(int inbuffer[], int outbuffer[]) { 073 int nLen = inbuffer.length; 074 for(int nI = 0; nI < nLen; nI += 2) { 075 long lTemp = Blowfish.intArrayToLong(inbuffer, nI); 076 lTemp = encryptBlockCBC(lTemp); 077 Blowfish.longToIntArray(lTemp, outbuffer, nI); 078 } 079 080 } 081 082 public void encrypt(int buffer[]) { 083 int nLen = buffer.length; 084 for(int nI = 0; nI < nLen; nI += 2) { 085 long lTemp = Blowfish.intArrayToLong(buffer, nI); 086 lTemp = encryptBlockCBC(lTemp); 087 Blowfish.longToIntArray(lTemp, buffer, nI); 088 } 089 090 } 091 092 public void encrypt(long inbuffer[], long outbuffer[]) { 093 int nLen = inbuffer.length; 094 for(int nI = 0; nI < nLen; nI++) 095 outbuffer[nI] = encryptBlockCBC(inbuffer[nI]); 096 097 } 098 099 public void encrypt(long buffer[]) { 100 int nLen = buffer.length; 101 for(int nI = 0; nI < nLen; nI++) 102 buffer[nI] = encryptBlockCBC(buffer[nI]); 103 104 } 105 106 public void decrypt(byte inbuffer[], byte outbuffer[]) { 107 int nLen = inbuffer.length; 108 for(int nI = 0; nI < nLen; nI += 8) { 109 long lTemp = Blowfish.byteArrayToLong(inbuffer, nI); 110 lTemp = decryptBlockCBC(lTemp); 111 Blowfish.longToByteArray(lTemp, outbuffer, nI); 112 } 113 114 } 115 116 public void decrypt(byte buffer[]) { 117 int nLen = buffer.length; 118 for(int nI = 0; nI < nLen; nI += 8) { 119 long lTemp = Blowfish.byteArrayToLong(buffer, nI); 120 lTemp = decryptBlockCBC(lTemp); 121 Blowfish.longToByteArray(lTemp, buffer, nI); 122 } 123 124 } 125 126 public void decrypt(int inbuffer[], int outbuffer[]) { 127 int nLen = inbuffer.length; 128 for(int nI = 0; nI < nLen; nI += 2) { 129 long lTemp = Blowfish.intArrayToLong(inbuffer, nI); 130 lTemp = decryptBlockCBC(lTemp); 131 Blowfish.longToIntArray(lTemp, outbuffer, nI); 132 } 133 134 } 135 136 public void decrypt(int buffer[]) { 137 int nLen = buffer.length; 138 for(int nI = 0; nI < nLen; nI += 2) { 139 long lTemp = Blowfish.intArrayToLong(buffer, nI); 140 lTemp = decryptBlockCBC(lTemp); 141 Blowfish.longToIntArray(lTemp, buffer, nI); 142 } 143 144 } 145 146 public void decrypt(long inbuffer[], long outbuffer[]) { 147 int nLen = inbuffer.length; 148 for(int nI = 0; nI < nLen; nI++) 149 outbuffer[nI] = decryptBlockCBC(inbuffer[nI]); 150 151 } 152 153 public void decrypt(long buffer[]) { 154 int nLen = buffer.length; 155 for(int nI = 0; nI < nLen; nI++) 156 buffer[nI] = decryptBlockCBC(buffer[nI]); 157 158 } 159 160 public BlowfishCBC(byte bfkey[]) { 161 super(bfkey); 162 setCBCIV(0L); 163 } 164 165 public BlowfishCBC(byte bfkey[], long lInitCBCIV) { 166 super(bfkey); 167 setCBCIV(lInitCBCIV); 168 } 169 170 public BlowfishCBC(byte bfkey[], byte initCBCIV[]) { 171 super(bfkey); 172 setCBCIV(initCBCIV); 173 } 174 } 175 176 private static class BlowfishECB { 177 178 //public static final int MAXKEYLENGTH = 56; 179 //public static final int BLOCKSIZE = 8; 180 //static final int PBOX_ENTRIES = 18; 181 //static final int SBOX_ENTRIES = 256; 182 int m_pbox[]; 183 int m_sbox1[]; 184 int m_sbox2[]; 185 int m_sbox3[]; 186 int m_sbox4[]; 187 static final int pbox_init[] = { 188 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x3707344, 0xa4093822, 0x299f31d0, 0x82efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 189 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b 190 }; 191 static final int sbox_init_1[] = { 192 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 193 0x801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0xd95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 194 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 195 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 196 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 197 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 198 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 199 0xf6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 200 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 201 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 202 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x75372c9, 0x80991b7b, 203 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x4c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 204 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 205 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 206 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 207 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 208 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 209 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 210 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 211 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 212 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 213 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 214 0x250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 215 0x207d5ba2, 0x2e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 216 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x8ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 217 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x8ba4799, 0x6e85076a 218 }; 219 static final int sbox_init_2[] = { 220 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 221 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 222 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x21ecc5e, 0x9686b3f, 0x3ebaefc9, 223 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 224 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 225 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0xfd0030e, 0xecc8c73e, 0xa4751e41, 226 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 227 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 228 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 229 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 230 0x43556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 231 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 232 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 233 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x18cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 234 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 235 0x334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 236 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 237 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0xe358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 238 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 239 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 240 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 241 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x95bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 242 0x58428d2a, 0xc55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 243 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 244 0x9e447a2e, 0xc3453484, 0xfdd56705, 0xe1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 245 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 246 }; 247 static final int sbox_init_3[] = { 248 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 249 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 250 0xbfbc09ec, 0x3bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 251 0xa2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 252 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 253 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 254 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 255 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x4272f70, 0x80bb155c, 0x5282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 256 0x7f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 257 0xdff8e8a3, 0x1f636c1b, 0xe12b4c2, 0x2e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 258 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 259 0xc39dfd27, 0xf33e8d1e, 0xa476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 260 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 261 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 262 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x6a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 263 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0xa121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 264 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 265 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 266 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 267 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 268 0xe85a1f02, 0x9f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0xba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 269 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0xde6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 270 0xf0177a28, 0xc0f586e0, 0x6058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 271 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 272 0xed545578, 0x8fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 273 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 274 }; 275 static final int sbox_init_4[] = { 276 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 277 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 278 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 279 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 280 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 281 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x22b8b51, 0x96d5ac3a, 0x17da67d, 0xd1cf3ed6, 0x7c7d2d28, 282 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 283 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x3a16125, 0x564f0bd, 284 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 285 0x3563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 286 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 287 0x69852dfd, 0x9072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 288 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 289 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x115af84, 290 0xe1b00428, 0x95983a1d, 0x6b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x11a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 291 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 292 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 293 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0xf91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 294 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 295 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0xfe3f11d, 296 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 297 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 298 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 299 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 300 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x2fb8a8c, 0x1c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 301 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 302 }; 303 304 public void cleanUp() { 305 for(int nI = 0; nI < 18; nI++) 306 m_pbox[nI] = 0; 307 308 for(int nI = 0; nI < 256; nI++) 309 m_sbox1[nI] = m_sbox2[nI] = m_sbox3[nI] = m_sbox4[nI] = 0; 310 311 } 312 313 public static boolean selfTest() { 314 byte testKey1[] = { 315 28, 88, 127, 28, 19, -110, 79, -17 316 }; 317 int tv_p1[] = { 318 0x30553228, 0x6d6f295a 319 }; 320 int tv_c1[] = { 321 0x55cb3774, 0xd13ef201 322 }; 323 int tv_t1[] = new int[2]; 324 String sTestKey2 = "Who is John Galt?"; 325 byte testKey2[] = sTestKey2.getBytes(); 326 int tv_p2[] = { 327 0xfedcba98, 0x76543210 328 }; 329 int tv_c2[] = { 330 0xcc91732b, 0x8022f684 331 }; 332 int tv_t2[] = new int[2]; 333 BlowfishECB testbf1 = new BlowfishECB(testKey1); 334 testbf1.encrypt(tv_p1, tv_t1); 335 if(tv_t1[0] != tv_c1[0] || tv_t1[1] != tv_c1[1]) 336 return false; 337 testbf1.decrypt(tv_t1); 338 if(tv_t1[0] != tv_p1[0] || tv_t1[1] != tv_p1[1]) 339 return false; 340 BlowfishECB testbf2 = new BlowfishECB(testKey2); 341 testbf2.encrypt(tv_p2, tv_t2); 342 if(tv_t2[0] != tv_c2[0] || tv_t2[1] != tv_c2[1]) 343 return false; 344 testbf2.decrypt(tv_t2); 345 return tv_t2[0] == tv_p2[0] && tv_t2[1] == tv_p2[1]; 346 } 347 348 protected long encryptBlock(long lPlainBlock) { 349 int nHi = Blowfish.longHi32(lPlainBlock); 350 int nLo = Blowfish.longLo32(lPlainBlock); 351 int sbox1[] = m_sbox1; 352 int sbox2[] = m_sbox2; 353 int sbox3[] = m_sbox3; 354 int sbox4[] = m_sbox4; 355 int pbox[] = m_pbox; 356 nHi ^= pbox[0]; 357 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[1]; 358 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[2]; 359 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[3]; 360 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[4]; 361 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[5]; 362 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[6]; 363 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[7]; 364 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[8]; 365 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[9]; 366 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[10]; 367 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[11]; 368 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[12]; 369 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[13]; 370 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[14]; 371 nLo ^= (sbox1[nHi >>> 24] + sbox2[nHi >>> 16 & 0xff] ^ sbox3[nHi >>> 8 & 0xff]) + sbox4[nHi & 0xff] ^ pbox[15]; 372 nHi ^= (sbox1[nLo >>> 24] + sbox2[nLo >>> 16 & 0xff] ^ sbox3[nLo >>> 8 & 0xff]) + sbox4[nLo & 0xff] ^ pbox[16]; 373 return Blowfish.makeLong(nHi, nLo ^ pbox[17]); 374 } 375 376 protected long decryptBlock(long lCipherBlock) { 377 int nHi = Blowfish.longHi32(lCipherBlock); 378 int nLo = Blowfish.longLo32(lCipherBlock); 379 nHi ^= m_pbox[17]; 380 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[16]; 381 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[15]; 382 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[14]; 383 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[13]; 384 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[12]; 385 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[11]; 386 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[10]; 387 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[9]; 388 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[8]; 389 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[7]; 390 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[6]; 391 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[5]; 392 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[4]; 393 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[3]; 394 nLo ^= (m_sbox1[nHi >>> 24] + m_sbox2[nHi >>> 16 & 0xff] ^ m_sbox3[nHi >>> 8 & 0xff]) + m_sbox4[nHi & 0xff] ^ m_pbox[2]; 395 nHi ^= (m_sbox1[nLo >>> 24] + m_sbox2[nLo >>> 16 & 0xff] ^ m_sbox3[nLo >>> 8 & 0xff]) + m_sbox4[nLo & 0xff] ^ m_pbox[1]; 396 return Blowfish.makeLong(nHi, nLo ^ m_pbox[0]); 397 } 398 399 public void encrypt(byte inbuffer[], byte outbuffer[]) { 400 int nLen = inbuffer.length; 401 for(int nI = 0; nI < nLen; nI += 8) { 402 long lTemp = Blowfish.byteArrayToLong(inbuffer, nI); 403 lTemp = encryptBlock(lTemp); 404 Blowfish.longToByteArray(lTemp, outbuffer, nI); 405 } 406 407 } 408 409 public void encrypt(byte buffer[]) { 410 int nLen = buffer.length; 411 for(int nI = 0; nI < nLen; nI += 8) { 412 long lTemp = Blowfish.byteArrayToLong(buffer, nI); 413 lTemp = encryptBlock(lTemp); 414 Blowfish.longToByteArray(lTemp, buffer, nI); 415 } 416 417 } 418 419 public void encrypt(int inbuffer[], int outbuffer[]) { 420 int nLen = inbuffer.length; 421 for(int nI = 0; nI < nLen; nI += 2) { 422 long lTemp = Blowfish.intArrayToLong(inbuffer, nI); 423 lTemp = encryptBlock(lTemp); 424 Blowfish.longToIntArray(lTemp, outbuffer, nI); 425 } 426 427 } 428 429 public void encrypt(int buffer[]) { 430 int nLen = buffer.length; 431 for(int nI = 0; nI < nLen; nI += 2) { 432 long lTemp = Blowfish.intArrayToLong(buffer, nI); 433 lTemp = encryptBlock(lTemp); 434 Blowfish.longToIntArray(lTemp, buffer, nI); 435 } 436 437 } 438 439 public void encrypt(long inbuffer[], long outbuffer[]) { 440 int nLen = inbuffer.length; 441 for(int nI = 0; nI < nLen; nI++) 442 outbuffer[nI] = encryptBlock(inbuffer[nI]); 443 444 } 445 446 public void encrypt(long buffer[]) { 447 int nLen = buffer.length; 448 for(int nI = 0; nI < nLen; nI++) 449 buffer[nI] = encryptBlock(buffer[nI]); 450 451 } 452 453 public void decrypt(byte inbuffer[], byte outbuffer[]) { 454 int nLen = inbuffer.length; 455 for(int nI = 0; nI < nLen; nI += 8) { 456 long lTemp = Blowfish.byteArrayToLong(inbuffer, nI); 457 lTemp = decryptBlock(lTemp); 458 Blowfish.longToByteArray(lTemp, outbuffer, nI); 459 } 460 461 } 462 463 public void decrypt(byte buffer[]) { 464 int nLen = buffer.length; 465 for(int nI = 0; nI < nLen; nI += 8) { 466 long lTemp = Blowfish.byteArrayToLong(buffer, nI); 467 lTemp = decryptBlock(lTemp); 468 Blowfish.longToByteArray(lTemp, buffer, nI); 469 } 470 471 } 472 473 public void decrypt(int inbuffer[], int outbuffer[]) { 474 int nLen = inbuffer.length; 475 for(int nI = 0; nI < nLen; nI += 2) { 476 long lTemp = Blowfish.intArrayToLong(inbuffer, nI); 477 lTemp = decryptBlock(lTemp); 478 Blowfish.longToIntArray(lTemp, outbuffer, nI); 479 } 480 481 } 482 483 public void decrypt(int buffer[]) { 484 int nLen = buffer.length; 485 for(int nI = 0; nI < nLen; nI += 2) { 486 long lTemp = Blowfish.intArrayToLong(buffer, nI); 487 lTemp = decryptBlock(lTemp); 488 Blowfish.longToIntArray(lTemp, buffer, nI); 489 } 490 491 } 492 493 public void decrypt(long inbuffer[], long outbuffer[]) { 494 int nLen = inbuffer.length; 495 for(int nI = 0; nI < nLen; nI++) 496 outbuffer[nI] = decryptBlock(inbuffer[nI]); 497 498 } 499 500 public void decrypt(long buffer[]) { 501 int nLen = buffer.length; 502 for(int nI = 0; nI < nLen; nI++) 503 buffer[nI] = decryptBlock(buffer[nI]); 504 505 } 506 507 508 public BlowfishECB(byte bfkey[]) { 509 m_pbox = new int[18]; 510 for(int nI = 0; nI < 18; nI++) 511 m_pbox[nI] = pbox_init[nI]; 512 513 m_sbox1 = new int[256]; 514 m_sbox2 = new int[256]; 515 m_sbox3 = new int[256]; 516 m_sbox4 = new int[256]; 517 for(int nI = 0; nI < 256; nI++) { 518 m_sbox1[nI] = sbox_init_1[nI]; 519 m_sbox2[nI] = sbox_init_2[nI]; 520 m_sbox3[nI] = sbox_init_3[nI]; 521 m_sbox4[nI] = sbox_init_4[nI]; 522 } 523 524 int nLen = bfkey.length; 525 if(nLen == 0) 526 return; 527 int nKeyPos = 0; 528 int nBuild = 0; 529 for(int nI = 0; nI < 18; nI++) { 530 for(int nJ = 0; nJ < 4; nJ++) { 531 nBuild = nBuild << 8 | bfkey[nKeyPos] & 0xff; 532 if(++nKeyPos == nLen) 533 nKeyPos = 0; 534 } 535 536 m_pbox[nI] ^= nBuild; 537 } 538 539 long lZero = 0L; 540 for(int nI = 0; nI < 18; nI += 2) { 541 lZero = encryptBlock(lZero); 542 m_pbox[nI] = (int)(lZero >>> 32); 543 m_pbox[nI + 1] = (int)(lZero & 0xffffffffL); 544 } 545 546 for(int nI = 0; nI < 256; nI += 2) { 547 lZero = encryptBlock(lZero); 548 m_sbox1[nI] = (int)(lZero >>> 32); 549 m_sbox1[nI + 1] = (int)(lZero & 0xffffffffL); 550 } 551 552 for(int nI = 0; nI < 256; nI += 2) { 553 lZero = encryptBlock(lZero); 554 m_sbox2[nI] = (int)(lZero >>> 32); 555 m_sbox2[nI + 1] = (int)(lZero & 0xffffffffL); 556 } 557 558 for(int nI = 0; nI < 256; nI += 2) { 559 lZero = encryptBlock(lZero); 560 m_sbox3[nI] = (int)(lZero >>> 32); 561 m_sbox3[nI + 1] = (int)(lZero & 0xffffffffL); 562 } 563 564 for(int nI = 0; nI < 256; nI += 2) { 565 lZero = encryptBlock(lZero); 566 m_sbox4[nI] = (int)(lZero >>> 32); 567 m_sbox4[nI + 1] = (int)(lZero & 0xffffffffL); 568 } 569 570 } 571 } 572 573 574 private BlowfishCBC m_bfish; 575 private static Random m_rndGen = new Random(); 576 static final char HEXTAB[] = { 577 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 578 'a', 'b', 'c', 'd', 'e', 'f' 579 }; 580 581 public Blowfish(String password) { 582 MessageDigest digest = null; 583 try { 584 digest = MessageDigest.getInstance("SHA1"); 585 digest.update(password.getBytes()); 586 } 587 catch(Exception e) { 588 ExceptionHandler.printStackTrace(e); 589 } 590 m_bfish = new BlowfishCBC(digest.digest(), 0L); 591 digest.reset(); 592 } 593 594 public String encryptString(String sPlainText) { 595 long lCBCIV; 596 synchronized(m_rndGen) { 597 lCBCIV = m_rndGen.nextLong(); 598 } 599 return encStr(sPlainText, lCBCIV); 600 } 601 602 private String encStr(String sPlainText, long lNewCBCIV) { 603 int nStrLen = sPlainText.length(); 604 byte buf[] = new byte[(nStrLen << 1 & -8) + 8]; 605 int nPos = 0; 606 for(int nI = 0; nI < nStrLen; nI++) { 607 char cActChar = sPlainText.charAt(nI); 608 buf[nPos++] = (byte)(cActChar >> 8 & 0xff); 609 buf[nPos++] = (byte)(cActChar & 0xff); 610 } 611 612 byte bPadVal = (byte)(buf.length - (nStrLen << 1)); 613 while(nPos < buf.length) 614 buf[nPos++] = bPadVal; 615 m_bfish.setCBCIV(lNewCBCIV); 616 m_bfish.encrypt(buf); 617 byte newCBCIV[] = new byte[8]; 618 longToByteArray(lNewCBCIV, newCBCIV, 0); 619 return bytesToBinHex(newCBCIV, 0, 8) + bytesToBinHex(buf, 0, buf.length); 620 } 621 622 public String decryptString(String sCipherText) { 623 int nLen = sCipherText.length() >> 1 & -8; 624 if(nLen < 8) 625 return null; 626 byte cbciv[] = new byte[8]; 627 int nNumOfBytes = binHexToBytes(sCipherText, cbciv, 0, 0, 8); 628 if(nNumOfBytes < 8) 629 return null; 630 m_bfish.setCBCIV(cbciv); 631 if((nLen -= 8) == 0) 632 return ""; 633 byte buf[] = new byte[nLen]; 634 nNumOfBytes = binHexToBytes(sCipherText, buf, 16, 0, nLen); 635 if(nNumOfBytes < nLen) 636 return null; 637 m_bfish.decrypt(buf); 638 int nPadByte = buf[buf.length - 1] & 0xff; 639 if(nPadByte > 8 || nPadByte < 0) 640 nPadByte = 0; 641 nNumOfBytes -= nPadByte; 642 if(nNumOfBytes < 0) 643 return ""; 644 return byteArrayToUNCString(buf, 0, nNumOfBytes); 645 } 646 647 public void destroy() { 648 m_bfish.cleanUp(); 649 } 650 651 private static long byteArrayToLong(byte buffer[], int nStartIndex) { 652 return (long)buffer[nStartIndex] << 56 | (buffer[nStartIndex + 1] & 255L) << 48 | (buffer[nStartIndex + 2] & 255L) << 40 | (buffer[nStartIndex + 3] & 255L) << 32 | (buffer[nStartIndex + 4] & 255L) << 24 | (buffer[nStartIndex + 5] & 255L) << 16 | (buffer[nStartIndex + 6] & 255L) << 8 | buffer[nStartIndex + 7] & 255L; 653 } 654 655 private static void longToByteArray(long lValue, byte buffer[], int nStartIndex) { 656 buffer[nStartIndex] = (byte)(int)(lValue >>> 56); 657 buffer[nStartIndex + 1] = (byte)(int)(lValue >>> 48 & 255L); 658 buffer[nStartIndex + 2] = (byte)(int)(lValue >>> 40 & 255L); 659 buffer[nStartIndex + 3] = (byte)(int)(lValue >>> 32 & 255L); 660 buffer[nStartIndex + 4] = (byte)(int)(lValue >>> 24 & 255L); 661 buffer[nStartIndex + 5] = (byte)(int)(lValue >>> 16 & 255L); 662 buffer[nStartIndex + 6] = (byte)(int)(lValue >>> 8 & 255L); 663 buffer[nStartIndex + 7] = (byte)(int)lValue; 664 } 665 666 private static long intArrayToLong(int buffer[], int nStartIndex) { 667 return (long)buffer[nStartIndex] << 32 | buffer[nStartIndex + 1] & 0xffffffffL; 668 } 669 670 private static void longToIntArray(long lValue, int buffer[], int nStartIndex) { 671 buffer[nStartIndex] = (int)(lValue >>> 32); 672 buffer[nStartIndex + 1] = (int)lValue; 673 } 674 675 private static long makeLong(int nLo, int nHi) { 676 return (long)nHi << 32 | nLo & 0xffffffffL; 677 } 678 679 private static int longLo32(long lVal) { 680 return (int)lVal; 681 } 682 683 private static int longHi32(long lVal) { 684 return (int)(lVal >>> 32); 685 } 686 687 private static String bytesToBinHex(byte data[], int nStartPos, int nNumOfBytes) { 688 StringBuffer sbuf = new StringBuffer(); 689 sbuf.setLength(nNumOfBytes << 1); 690 int nPos = 0; 691 for(int nI = 0; nI < nNumOfBytes; nI++) { 692 sbuf.setCharAt(nPos++, HEXTAB[data[nI + nStartPos] >> 4 & 0xf]); 693 sbuf.setCharAt(nPos++, HEXTAB[data[nI + nStartPos] & 0xf]); 694 } 695 696 return sbuf.toString(); 697 } 698 699 private static int binHexToBytes(String sBinHex, byte data[], int nSrcPos, int nDstPos, int nNumOfBytes) { 700 int nStrLen = sBinHex.length(); 701 int nAvailBytes = nStrLen - nSrcPos >> 1; 702 if(nAvailBytes < nNumOfBytes) 703 nNumOfBytes = nAvailBytes; 704 int nOutputCapacity = data.length - nDstPos; 705 if(nNumOfBytes > nOutputCapacity) 706 nNumOfBytes = nOutputCapacity; 707 int nResult = 0; 708 for(int nI = 0; nI < nNumOfBytes; nI++) { 709 byte bActByte = 0; 710 boolean blConvertOK = true; 711 for(int nJ = 0; nJ < 2; nJ++) { 712 bActByte <<= 4; 713 char cActChar = sBinHex.charAt(nSrcPos++); 714 if(cActChar >= 'a' && cActChar <= 'f') { 715 bActByte |= (byte)(cActChar - 97) + 10; 716 continue; 717 } 718 if(cActChar >= '0' && cActChar <= '9') 719 bActByte |= (byte)(cActChar - 48); 720 else 721 blConvertOK = false; 722 } 723 724 if(blConvertOK) { 725 data[nDstPos++] = bActByte; 726 nResult++; 727 } 728 } 729 730 return nResult; 731 } 732 733 private static String byteArrayToUNCString(byte data[], int nStartPos, int nNumOfBytes) { 734 nNumOfBytes &= -2; 735 int nAvailCapacity = data.length - nStartPos; 736 if(nAvailCapacity < nNumOfBytes) 737 nNumOfBytes = nAvailCapacity; 738 StringBuffer sbuf = new StringBuffer(); 739 sbuf.setLength(nNumOfBytes >> 1); 740 int nSBufPos = 0; 741 for(; nNumOfBytes > 0; nNumOfBytes -= 2) { 742 sbuf.setCharAt(nSBufPos++, (char)(data[nStartPos] << 8 | data[nStartPos + 1] & 0xff)); 743 nStartPos += 2; 744 } 745 746 return sbuf.toString(); 747 } 748 }