1 29 30 package com.caucho.quercus.lib.mcrypt; 31 32 import com.caucho.quercus.QuercusRuntimeException; 33 import com.caucho.quercus.env.ArrayValue; 34 import com.caucho.quercus.env.ArrayValueImpl; 35 import com.caucho.quercus.env.Env; 36 import com.caucho.quercus.env.Value; 37 import com.caucho.util.L10N; 38 39 import javax.crypto.Cipher; 40 import javax.crypto.spec.IvParameterSpec; 41 import javax.crypto.spec.SecretKeySpec; 42 import java.security.Key ; 43 import java.util.logging.Logger ; 44 45 48 public class Mcrypt { 49 private static final L10N L = new L10N(Mcrypt.class); 50 51 private static final Logger log = 52 Logger.getLogger(Mcrypt.class.getName()); 53 54 private final String _algorithm; 55 private final String _mode; 56 57 private final Cipher _cipher; 58 59 private Key _key; 60 private IvParameterSpec _iv; 61 62 Mcrypt(Env env, String algorithm, String mode) 63 throws Exception 64 { 65 _algorithm = algorithm; 66 _mode = mode.toUpperCase(); 67 68 String transformation = getTransformation(algorithm, mode); 69 70 if (transformation == null) 71 throw new QuercusRuntimeException(L.l("'{0}' is an unknown algorithm", 72 algorithm)); 73 74 75 _cipher = Cipher.getInstance(transformation); 76 } 77 78 81 public boolean deinit() 82 { 83 return false; 84 } 85 86 89 public byte []decrypt(byte []data) 90 { 91 try { 92 _cipher.init(Cipher.DECRYPT_MODE, _key, _iv); 93 94 int blockSize = _cipher.getBlockSize(); 95 96 return _cipher.doFinal(data); 97 } catch (Exception e) { 98 throw new RuntimeException (e); 99 } 100 } 101 102 105 public byte []encrypt(byte []data) 106 { 107 try { 108 _cipher.init(Cipher.ENCRYPT_MODE, _key, _iv); 109 110 if (isPadded()) 111 data = pad(data); 112 113 return _cipher.doFinal(data); 114 } catch (Exception e) { 115 throw new RuntimeException (e); 116 } 117 } 118 119 122 public int get_block_size() 123 { 124 return _cipher.getBlockSize(); 125 } 126 127 130 public String get_algorithms_name() 131 { 132 return _algorithm; 133 } 134 135 138 public int get_iv_size() 139 { 140 if (_mode.equals("OFB")) 141 return _cipher.getBlockSize(); 142 else if (_mode.equals("CFB")) 143 return _cipher.getBlockSize(); 144 if (_mode.equals("CBC")) 145 return _cipher.getBlockSize(); 146 else 147 return 0; 148 } 149 150 153 public Value get_supported_key_sizes() 154 { 155 ArrayValue value = new ArrayValueImpl(); 156 157 if (McryptModule.MCRYPT_RIJNDAEL_128.equals(_algorithm)) { 158 value.put(128 / 8); 159 } 160 else if (McryptModule.MCRYPT_RIJNDAEL_192.equals(_algorithm)) { 161 value.put(128 / 8); 162 value.put(192 / 8); 163 } 164 else if (McryptModule.MCRYPT_RIJNDAEL_256.equals(_algorithm)) { 165 value.put(128 / 8); 166 value.put(192 / 8); 167 value.put(256 / 8); 168 } 169 else if (McryptModule.MCRYPT_3DES.equals(_algorithm)) { 170 value.put(24); 171 } 172 else if (McryptModule.MCRYPT_DES.equals(_algorithm)) { 173 value.put(8); 174 } 175 176 return value; 177 } 178 179 182 public int get_key_size() 183 { 184 if (McryptModule.MCRYPT_RIJNDAEL_128.equals(_algorithm)) 185 return 128 / 8; 186 else if (McryptModule.MCRYPT_RIJNDAEL_192.equals(_algorithm)) 187 return 192 / 8; 188 else if (McryptModule.MCRYPT_RIJNDAEL_256.equals(_algorithm)) 189 return 256 / 8; 190 else if (McryptModule.MCRYPT_3DES.equals(_algorithm)) 191 return 24; 192 else if (McryptModule.MCRYPT_BLOWFISH.equals(_algorithm)) 193 return 56; 194 else 195 return get_block_size(); 196 } 197 198 201 public String get_modes_name() 202 { 203 return _mode; 204 } 205 206 209 public int init(String keyString, String iv) 210 { 211 byte []keyBytes = new byte[get_key_size()]; 212 213 for (int i = 0; i < keyString.length() && i < keyBytes.length; i++) 214 keyBytes[i] = (byte) keyString.charAt(i); 215 216 _key = new SecretKeySpec(keyBytes, getAlgorithm(_algorithm)); 217 218 if (_mode.equals("CBC") || _mode.equals("CFB") || _mode.equals("OFB")) 219 _iv = new IvParameterSpec(iv.getBytes()); 220 else 221 _iv = null; 222 223 return 0; 224 } 225 226 229 public boolean is_block_algorithm() 230 { 231 if (_algorithm.equals(McryptModule.MCRYPT_BLOWFISH)) 232 return false; 233 else 234 return true; 235 } 236 237 240 public boolean is_block_algorithm_mode() 241 { 242 return _mode.equals("CBC") || _mode.equals("CFB") || _mode.equals("OFB"); 243 } 244 245 248 public boolean is_block_mode() 249 { 250 return _mode.equals("CBC") || _mode.equals("ECB"); 251 } 252 253 private byte []pad(byte []data) 254 { 255 int blockSize = get_block_size(); 256 257 int len = data.length; 258 int offset = len % blockSize; 259 260 if (offset == 0) 261 return data; 262 else { 263 byte []pad = new byte[len + blockSize - offset]; 264 265 System.arraycopy(data, 0, pad, 0, data.length); 266 267 return pad; 268 } 269 } 270 271 272 private boolean isPadded() 273 { 274 return (McryptModule.MCRYPT_DES.equals(_algorithm) || 275 McryptModule.MCRYPT_3DES.equals(_algorithm)); 276 } 277 278 281 public void close() 282 { 283 } 284 285 private static String getTransformation(String algorithm, String mode) 286 throws Exception 287 { 288 mode = mode.toUpperCase(); 289 if (McryptModule.MCRYPT_RIJNDAEL_128.equals(algorithm)) 290 return "AES/" + mode + "/NoPadding"; 291 else if (McryptModule.MCRYPT_RIJNDAEL_192.equals(algorithm)) 292 return "AES/" + mode + "192/NoPadding"; 293 else if (McryptModule.MCRYPT_RIJNDAEL_256.equals(algorithm)) 294 return "AES/" + mode + "256/NoPadding"; 295 else if (McryptModule.MCRYPT_DES.equals(algorithm)) 296 return "DES/" + mode + "/NoPadding"; 297 else if (McryptModule.MCRYPT_3DES.equals(algorithm)) 298 return "DESede/" + mode + "/NoPadding"; 299 else if (McryptModule.MCRYPT_BLOWFISH.equals(algorithm)) 300 return "Blowfish/" + mode + "/NoPadding"; 301 else if (McryptModule.MCRYPT_ARCFOUR.equals(algorithm) || 302 McryptModule.MCRYPT_RC4.equals(algorithm)) 303 return "ARCFOUR/" + mode + "/NoPadding"; 304 else 305 return algorithm + '/' + mode + "/NoPadding"; 306 } 307 308 private static String getAlgorithm(String algorithm) 309 { 310 if (McryptModule.MCRYPT_RIJNDAEL_128.equals(algorithm) || 311 McryptModule.MCRYPT_RIJNDAEL_192.equals(algorithm) || 312 McryptModule.MCRYPT_RIJNDAEL_256.equals(algorithm)) 313 return "AES"; 314 else if (McryptModule.MCRYPT_3DES.equals(algorithm)) 315 return "DESede"; 316 else 317 return algorithm; 318 } 319 320 public String toString() 321 { 322 return "Mcrypt[" + _algorithm + ", " + _mode + "]"; 323 } 324 } 325 | Popular Tags |