1 17 package org.alfresco.filesys.server.auth; 18 19 import java.io.UnsupportedEncodingException ; 20 import java.security.InvalidKeyException ; 21 import java.security.MessageDigest ; 22 import java.security.NoSuchAlgorithmException ; 23 24 import javax.crypto.BadPaddingException; 25 import javax.crypto.Cipher; 26 import javax.crypto.IllegalBlockSizeException; 27 import javax.crypto.NoSuchPaddingException; 28 import javax.crypto.spec.SecretKeySpec; 29 30 37 public class PasswordEncryptor 38 { 39 40 42 public static final int LANMAN = 0; 43 public static final int NTLM1 = 1; 44 public static final int NTLM2 = 2; 45 public static final int MD4 = 3; 46 47 49 private final static String [] _algNames = { "LanMan", "NTLMv1", "NTLMv2", "MD4" }; 50 51 54 public PasswordEncryptor() 55 { 56 } 57 58 63 public static final boolean checkEncryptionAlgorithms() 64 { 65 66 boolean algOK = false; 67 68 try 69 { 70 71 73 MessageDigest.getInstance("MD4"); 74 75 77 Cipher.getInstance("DES"); 78 } 79 catch (NoSuchAlgorithmException ex) 80 { 81 } 82 catch (NoSuchPaddingException ex) 83 { 84 } 85 86 88 return algOK; 89 } 90 91 101 public byte[] generateEncryptedPassword(String plainPwd, byte[] encryptKey, int alg) 102 throws NoSuchAlgorithmException 103 { 104 105 107 String pwd = plainPwd; 108 if (pwd == null) 109 pwd = ""; 110 111 113 byte[] encPwd = null; 114 MessageDigest md4 = null; 115 int len = 0; 116 byte[] pwdBytes = null; 117 118 switch (alg) 119 { 120 121 123 case LANMAN: 124 encPwd = P24(pwd, encryptKey); 125 break; 126 127 129 case NTLM1: 130 131 133 md4 = MessageDigest.getInstance("MD4"); 134 135 try { 136 pwdBytes = pwd.getBytes("UnicodeLittleUnmarked"); 137 } 138 catch (UnsupportedEncodingException ex) { 139 } 140 141 md4.update(pwdBytes); 142 byte[] p21 = new byte[21]; 143 System.arraycopy(md4.digest(), 0, p21, 0, 16); 144 145 147 encPwd = P24(p21,encryptKey); 148 break; 149 150 152 case NTLM2: 153 break; 154 155 157 case MD4: 158 159 161 md4 = MessageDigest.getInstance("MD4"); 162 len = pwd.length(); 163 pwdBytes = new byte[len * 2]; 164 165 for (int i = 0; i < len; i++) 166 { 167 char ch = pwd.charAt(i); 168 pwdBytes[i * 2] = (byte) ch; 169 pwdBytes[i * 2 + 1] = (byte) ((ch >> 8) & 0xFF); 170 } 171 172 md4.update(pwdBytes); 173 encPwd = new byte[16]; 174 System.arraycopy(md4.digest(), 0, encPwd, 0, 16); 175 break; 176 } 177 178 180 return encPwd; 181 } 182 183 191 public final byte[] P16(String pwd, byte[] s8) throws NoSuchAlgorithmException 192 { 193 194 197 StringBuffer p14str = new StringBuffer (); 198 p14str.append(pwd.toUpperCase()); 199 if (p14str.length() > 14) 200 p14str.setLength(14); 201 202 while (p14str.length() < 14) 203 p14str.append((char) 0x00); 204 205 208 byte[] p14 = p14str.toString().getBytes(); 209 byte[] p16 = new byte[21]; 210 211 try 212 { 213 214 216 Cipher des = Cipher.getInstance("DES"); 217 218 221 byte[] key = generateKey(p14, 0); 222 223 SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES"); 224 des.init(Cipher.ENCRYPT_MODE, chKey); 225 byte[] res = des.doFinal(s8); 226 System.arraycopy(res, 0, p16, 0, 8); 227 228 230 key = generateKey(p14, 7); 231 232 chKey = new SecretKeySpec(key, 0, key.length, "DES"); 233 des.init(Cipher.ENCRYPT_MODE, chKey); 234 res = des.doFinal(s8); 235 System.arraycopy(res, 0, p16, 8, 8); 236 } 237 catch (NoSuchPaddingException ex) 238 { 239 p16 = null; 240 } 241 catch (IllegalBlockSizeException ex) 242 { 243 p16 = null; 244 } 245 catch (BadPaddingException ex) 246 { 247 p16 = null; 248 } 249 catch (InvalidKeyException ex) 250 { 251 p16 = null; 252 } 253 254 256 return p16; 257 } 258 259 267 private final byte[] P24(String pwd, byte[] c8) throws NoSuchAlgorithmException 268 { 269 270 273 byte[] s8 = new String ("KGS!@#$%").getBytes(); 274 byte[] p16 = P16(pwd, s8); 275 276 278 return P24(p16, c8); 279 } 280 281 289 private final byte[] P24(byte[] p21, byte[] ch) throws NoSuchAlgorithmException 290 { 291 292 byte[] enc = null; 293 294 try 295 { 296 297 299 Cipher des = Cipher.getInstance("DES"); 300 301 303 enc = new byte[24]; 304 305 307 byte[] key = generateKey(p21, 0); 308 309 SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES"); 310 des.init(Cipher.ENCRYPT_MODE, chKey); 311 byte[] res = des.doFinal(ch); 312 System.arraycopy(res, 0, enc, 0, 8); 313 314 316 key = generateKey(p21, 7); 317 318 chKey = new SecretKeySpec(key, 0, key.length, "DES"); 319 des.init(Cipher.ENCRYPT_MODE, chKey); 320 res = des.doFinal(ch); 321 System.arraycopy(res, 0, enc, 8, 8); 322 323 325 key = generateKey(p21, 14); 326 327 chKey = new SecretKeySpec(key, 0, key.length, "DES"); 328 des.init(Cipher.ENCRYPT_MODE, chKey); 329 res = des.doFinal(ch); 330 System.arraycopy(res, 0, enc, 16, 8); 331 } 332 catch (NoSuchPaddingException ex) 333 { 334 ex.printStackTrace(); 335 enc = null; 336 } 337 catch (IllegalBlockSizeException ex) 338 { 339 ex.printStackTrace(); 340 enc = null; 341 } 342 catch (BadPaddingException ex) 343 { 344 ex.printStackTrace(); 345 enc = null; 346 } 347 catch (InvalidKeyException ex) 348 { 349 ex.printStackTrace(); 350 enc = null; 351 } 352 353 355 return enc; 356 } 357 358 364 public static String getAlgorithmName(int alg) 365 { 366 if (alg >= 0 && alg < _algNames.length) 367 return _algNames[alg]; 368 return "Unknown"; 369 } 370 371 378 private byte[] generateKey(byte[] byt, int off) 379 { 380 381 383 byte[] key = new byte[8]; 384 385 387 key[0] = (byte) (byt[off + 0] >> 1); 388 key[1] = (byte) (((byt[off + 0] & 0x01) << 6) | ((byt[off + 1] & 0xFF) >> 2)); 389 key[2] = (byte) (((byt[off + 1] & 0x03) << 5) | ((byt[off + 2] & 0xFF) >> 3)); 390 key[3] = (byte) (((byt[off + 2] & 0x07) << 4) | ((byt[off + 3] & 0xFF) >> 4)); 391 key[4] = (byte) (((byt[off + 3] & 0x0F) << 3) | ((byt[off + 4] & 0xFF) >> 5)); 392 key[5] = (byte) (((byt[off + 4] & 0x1F) << 2) | ((byt[off + 5] & 0xFF) >> 6)); 393 key[6] = (byte) (((byt[off + 5] & 0x3F) << 1) | ((byt[off + 6] & 0xFF) >> 7)); 394 key[7] = (byte) (byt[off + 6] & 0x7F); 395 396 for (int i = 0; i < 8; i++) 397 { 398 key[i] = (byte) (key[i] << 1); 399 } 400 401 return key; 402 } 403 404 412 public final byte[] doNTLM1Encryption(byte[] p21, byte[] c8) 413 throws NoSuchAlgorithmException 414 { 415 return P24(p21, c8); 416 } 417 } 418 | Popular Tags |