5454 lines
		
	
	
		
			188 KiB
		
	
	
	
		
			Java
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			5454 lines
		
	
	
		
			188 KiB
		
	
	
	
		
			Java
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env compileAndGo
 | |
| # -*- coding: utf-8 mode: java -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| compiler=javac
 | |
| mainClass=upassword
 | |
| compileAndGo
 | |
| 
 | |
| import java.io.BufferedReader;
 | |
| import java.io.File;
 | |
| import java.io.FileInputStream;
 | |
| import java.io.FileOutputStream;
 | |
| import java.io.IOException;
 | |
| import java.io.InputStreamReader;
 | |
| import java.io.PrintWriter;
 | |
| import java.io.StringWriter;
 | |
| import java.io.UnsupportedEncodingException;
 | |
| import java.security.MessageDigest;
 | |
| import java.security.NoSuchAlgorithmException;
 | |
| import java.security.SecureRandom;
 | |
| import java.util.Arrays;
 | |
| import java.util.List;
 | |
| import java.util.Random;
 | |
| import java.util.concurrent.ThreadLocalRandom;
 | |
| import java.util.regex.Pattern;
 | |
| 
 | |
| import javax.crypto.Cipher;
 | |
| import javax.crypto.KeyGenerator;
 | |
| import javax.crypto.SecretKey;
 | |
| import javax.crypto.SecretKeyFactory;
 | |
| import javax.crypto.spec.PBEKeySpec;
 | |
| import javax.crypto.spec.SecretKeySpec;
 | |
| 
 | |
| public class upassword {
 | |
|     public static final String UTF_8 = "UTF-8";
 | |
| 
 | |
|     public static final int MIN_LEN = 8;
 | |
| 
 | |
|     public static final int MIN_UPPER = 0;
 | |
| 
 | |
|     public static final int MIN_LOWER = 0;
 | |
| 
 | |
|     public static final int MIN_ALPHA = 2;
 | |
| 
 | |
|     public static final int MIN_NUMBER = 0;
 | |
| 
 | |
|     public static final int MIN_SYMBOL = 0;
 | |
| 
 | |
|     public static final int MIN_SPECIAL = 2;
 | |
| 
 | |
|     public static final boolean ALLOW_MULTIBYTES = false;
 | |
| 
 | |
|     public static final String getSummary(Exception e) {
 | |
|         StringWriter sw = new StringWriter();
 | |
|         PrintWriter pw = new PrintWriter(sw);
 | |
|         e.printStackTrace(pw);
 | |
|         pw.flush();
 | |
|         return sw.toString();
 | |
|     }
 | |
| 
 | |
|     public static final void println(String text) {
 | |
|         System.out.println(text);
 | |
|         System.out.flush();
 | |
|     }
 | |
| 
 | |
|     public static final StringBuilder toHex(StringBuilder sb, byte b) {
 | |
|         if (sb == null) return null;
 | |
|         int l = b & 0x0F, u = (b & 0xF0) >> 4;
 | |
|         u += u < 10? '0': 'A' - 10;
 | |
|         l += l < 10? '0': 'A' - 10;
 | |
|         return sb.append((char)u).append((char)l);
 | |
|     }
 | |
| 
 | |
|     public static final String toHex(byte[] ba) {
 | |
|         if (ba == null) return null;
 | |
|         StringBuilder sb = new StringBuilder(2 * ba.length);
 | |
|         for (int i = 0; i < ba.length; i++) {
 | |
|             toHex(sb, ba[i]);
 | |
|         }
 | |
|         return sb.toString();
 | |
|     }
 | |
| 
 | |
|     public static final boolean isHex(String str) {
 | |
|         int l = str.length();
 | |
|         if (l % 2 != 0) return false;
 | |
|         for (int i = 0; i < l; i++) {
 | |
|             char c = str.charAt(i);
 | |
|             if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     public static final byte[] fromHex(String str) {
 | |
|         if (str == null) return null;
 | |
|         int l = str.length();
 | |
|         byte[] ba = new byte[l / 2];
 | |
|         int j = 0;
 | |
|         for (int i = 0; i < l; i += 2) {
 | |
|             byte b = (byte)Short.parseShort(str.substring(i, i + 2), 16);
 | |
|             ba[j++] = b;
 | |
|         }
 | |
|         return ba;
 | |
|     }
 | |
| 
 | |
|     public static final boolean strIsempty(String str) {
 | |
|         return str == null || str.length() == 0;
 | |
|     }
 | |
| 
 | |
|     public static final boolean strEquals(String s1, String s2) {
 | |
|         return s1 == s2 || (s1 != null && s1.equals(s2));
 | |
|     }
 | |
| 
 | |
|     public static final String strNotnull(String str) {
 | |
|         return str == null? "": str;
 | |
|     }
 | |
| 
 | |
|     public static final String strSubstr(String str, int start, int end) {
 | |
|         if (str == null) return null;
 | |
| 
 | |
|         int l = str.length();
 | |
|         if (l > 0) {
 | |
|             while (start < 0)
 | |
|                 start += l;
 | |
|             while (end < 0)
 | |
|                 end += l;
 | |
|         } else {
 | |
|             if (start < 0) start = 0;
 | |
|             if (end < 0) end = 0;
 | |
|         }
 | |
|         if (start >= l || start >= end) return "";
 | |
|         if (end >= l + 1) end = l;
 | |
| 
 | |
|         return str.substring(start, end);
 | |
|     }
 | |
| 
 | |
|     public static final String strSubstr(String str, int start) {
 | |
|         if (str == null) return null;
 | |
|         return strSubstr(str, start, str.length());
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class Base64 {
 | |
|         public final static int NO_OPTIONS = 0;
 | |
| 
 | |
|         public final static int ENCODE = 1;
 | |
| 
 | |
|         public final static int DECODE = 0;
 | |
| 
 | |
|         public final static int GZIP = 2;
 | |
| 
 | |
|         public final static int DONT_BREAK_LINES = 8;
 | |
| 
 | |
|         private final static int MAX_LINE_LENGTH = 76;
 | |
| 
 | |
|         private final static byte EQUALS_SIGN = (byte)'=';
 | |
| 
 | |
|         private final static byte NEW_LINE = (byte)'\n';
 | |
| 
 | |
|         private final static String PREFERRED_ENCODING = "UTF-8";
 | |
| 
 | |
|         private final static byte[] ALPHABET;
 | |
| 
 | |
|         private final static byte[] _NATIVE_ALPHABET = {
 | |
|                 (byte)'A',
 | |
|                 (byte)'B',
 | |
|                 (byte)'C',
 | |
|                 (byte)'D',
 | |
|                 (byte)'E',
 | |
|                 (byte)'F',
 | |
|                 (byte)'G',
 | |
|                 (byte)'H',
 | |
|                 (byte)'I',
 | |
|                 (byte)'J',
 | |
|                 (byte)'K',
 | |
|                 (byte)'L',
 | |
|                 (byte)'M',
 | |
|                 (byte)'N',
 | |
|                 (byte)'O',
 | |
|                 (byte)'P',
 | |
|                 (byte)'Q',
 | |
|                 (byte)'R',
 | |
|                 (byte)'S',
 | |
|                 (byte)'T',
 | |
|                 (byte)'U',
 | |
|                 (byte)'V',
 | |
|                 (byte)'W',
 | |
|                 (byte)'X',
 | |
|                 (byte)'Y',
 | |
|                 (byte)'Z',
 | |
|                 (byte)'a',
 | |
|                 (byte)'b',
 | |
|                 (byte)'c',
 | |
|                 (byte)'d',
 | |
|                 (byte)'e',
 | |
|                 (byte)'f',
 | |
|                 (byte)'g',
 | |
|                 (byte)'h',
 | |
|                 (byte)'i',
 | |
|                 (byte)'j',
 | |
|                 (byte)'k',
 | |
|                 (byte)'l',
 | |
|                 (byte)'m',
 | |
|                 (byte)'n',
 | |
|                 (byte)'o',
 | |
|                 (byte)'p',
 | |
|                 (byte)'q',
 | |
|                 (byte)'r',
 | |
|                 (byte)'s',
 | |
|                 (byte)'t',
 | |
|                 (byte)'u',
 | |
|                 (byte)'v',
 | |
|                 (byte)'w',
 | |
|                 (byte)'x',
 | |
|                 (byte)'y',
 | |
|                 (byte)'z',
 | |
|                 (byte)'0',
 | |
|                 (byte)'1',
 | |
|                 (byte)'2',
 | |
|                 (byte)'3',
 | |
|                 (byte)'4',
 | |
|                 (byte)'5',
 | |
|                 (byte)'6',
 | |
|                 (byte)'7',
 | |
|                 (byte)'8',
 | |
|                 (byte)'9',
 | |
|                 (byte)'+',
 | |
|                 (byte)'/'};
 | |
|         static {
 | |
|             byte[] __bytes;
 | |
|             try {
 | |
|                 __bytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 | |
|                         .getBytes(PREFERRED_ENCODING);
 | |
|             } catch (java.io.UnsupportedEncodingException use) {
 | |
|                 __bytes = _NATIVE_ALPHABET;
 | |
|             }
 | |
|             ALPHABET = __bytes;
 | |
|         }
 | |
| 
 | |
|         private final static byte[] DECODABET = {
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -5,
 | |
|                 -5,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -5,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -5,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 62,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 63,
 | |
|                 52,
 | |
|                 53,
 | |
|                 54,
 | |
|                 55,
 | |
|                 56,
 | |
|                 57,
 | |
|                 58,
 | |
|                 59,
 | |
|                 60,
 | |
|                 61,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -1,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 0,
 | |
|                 1,
 | |
|                 2,
 | |
|                 3,
 | |
|                 4,
 | |
|                 5,
 | |
|                 6,
 | |
|                 7,
 | |
|                 8,
 | |
|                 9,
 | |
|                 10,
 | |
|                 11,
 | |
|                 12,
 | |
|                 13,
 | |
|                 14,
 | |
|                 15,
 | |
|                 16,
 | |
|                 17,
 | |
|                 18,
 | |
|                 19,
 | |
|                 20,
 | |
|                 21,
 | |
|                 22,
 | |
|                 23,
 | |
|                 24,
 | |
|                 25,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 26,
 | |
|                 27,
 | |
|                 28,
 | |
|                 29,
 | |
|                 30,
 | |
|                 31,
 | |
|                 32,
 | |
|                 33,
 | |
|                 34,
 | |
|                 35,
 | |
|                 36,
 | |
|                 37,
 | |
|                 38,
 | |
|                 39,
 | |
|                 40,
 | |
|                 41,
 | |
|                 42,
 | |
|                 43,
 | |
|                 44,
 | |
|                 45,
 | |
|                 46,
 | |
|                 47,
 | |
|                 48,
 | |
|                 49,
 | |
|                 50,
 | |
|                 51,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9,
 | |
|                 -9};
 | |
| 
 | |
|         private final static byte WHITE_SPACE_ENC = -5;
 | |
| 
 | |
|         private final static byte EQUALS_SIGN_ENC = -1;
 | |
| 
 | |
|         private Base64() {
 | |
|         }
 | |
| 
 | |
|         private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes) {
 | |
|             encode3to4(threeBytes, 0, numSigBytes, b4, 0);
 | |
|             return b4;
 | |
|         }
 | |
| 
 | |
|         private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes,
 | |
|                 byte[] destination, int destOffset) {
 | |
|             int inBuff = (numSigBytes > 0? ((source[srcOffset] << 24) >>> 8): 0)
 | |
|                     | (numSigBytes > 1? ((source[srcOffset + 1] << 24) >>> 16): 0)
 | |
|                     | (numSigBytes > 2? ((source[srcOffset + 2] << 24) >>> 24): 0);
 | |
|             switch (numSigBytes) {
 | |
|             case 3:
 | |
|                 destination[destOffset] = ALPHABET[(inBuff >>> 18)];
 | |
|                 destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
 | |
|                 destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
 | |
|                 destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
 | |
|                 return destination;
 | |
|             case 2:
 | |
|                 destination[destOffset] = ALPHABET[(inBuff >>> 18)];
 | |
|                 destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
 | |
|                 destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
 | |
|                 destination[destOffset + 3] = EQUALS_SIGN;
 | |
|                 return destination;
 | |
|             case 1:
 | |
|                 destination[destOffset] = ALPHABET[(inBuff >>> 18)];
 | |
|                 destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
 | |
|                 destination[destOffset + 2] = EQUALS_SIGN;
 | |
|                 destination[destOffset + 3] = EQUALS_SIGN;
 | |
|                 return destination;
 | |
|             default:
 | |
|                 return destination;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static String encodeObject(java.io.Serializable serializableObject) {
 | |
|             return encodeObject(serializableObject, NO_OPTIONS);
 | |
|         }
 | |
| 
 | |
|         public static String encodeObject(java.io.Serializable serializableObject, int options) {
 | |
|             java.io.ByteArrayOutputStream baos = null;
 | |
|             java.io.OutputStream b64os = null;
 | |
|             java.io.ObjectOutputStream oos = null;
 | |
|             java.util.zip.GZIPOutputStream gzos = null;
 | |
|             int gzip = (options & GZIP);
 | |
|             int dontBreakLines = (options & DONT_BREAK_LINES);
 | |
|             try {
 | |
|                 baos = new java.io.ByteArrayOutputStream();
 | |
|                 b64os = new Base64.OutputStream(baos, ENCODE | dontBreakLines);
 | |
|                 if (gzip == GZIP) {
 | |
|                     gzos = new java.util.zip.GZIPOutputStream(b64os);
 | |
|                     oos = new java.io.ObjectOutputStream(gzos);
 | |
|                 } else oos = new java.io.ObjectOutputStream(b64os);
 | |
|                 oos.writeObject(serializableObject);
 | |
|             } catch (java.io.IOException e) {
 | |
|                 e.printStackTrace();
 | |
|                 return null;
 | |
|             } finally {
 | |
|                 try {
 | |
|                     oos.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|                 try {
 | |
|                     gzos.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|                 try {
 | |
|                     b64os.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|                 try {
 | |
|                     baos.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             try {
 | |
|                 return new String(baos.toByteArray(), PREFERRED_ENCODING);
 | |
|             } catch (java.io.UnsupportedEncodingException uue) {
 | |
|                 return new String(baos.toByteArray());
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static String encodeBytes(byte[] source) {
 | |
|             return encodeBytes(source, 0, source.length, NO_OPTIONS);
 | |
|         }
 | |
| 
 | |
|         public static String encodeBytes(byte[] source, int options) {
 | |
|             return encodeBytes(source, 0, source.length, options);
 | |
|         }
 | |
| 
 | |
|         public static String encodeBytes(byte[] source, int off, int len) {
 | |
|             return encodeBytes(source, off, len, NO_OPTIONS);
 | |
|         }
 | |
| 
 | |
|         public static String encodeBytes(byte[] source, int off, int len, int options) {
 | |
|             int dontBreakLines = (options & DONT_BREAK_LINES);
 | |
|             int gzip = (options & GZIP);
 | |
|             if (gzip == GZIP) {
 | |
|                 java.io.ByteArrayOutputStream baos = null;
 | |
|                 java.util.zip.GZIPOutputStream gzos = null;
 | |
|                 Base64.OutputStream b64os = null;
 | |
|                 try {
 | |
|                     baos = new java.io.ByteArrayOutputStream();
 | |
|                     b64os = new Base64.OutputStream(baos, ENCODE | dontBreakLines);
 | |
|                     gzos = new java.util.zip.GZIPOutputStream(b64os);
 | |
|                     gzos.write(source, off, len);
 | |
|                     gzos.close();
 | |
|                 } catch (java.io.IOException e) {
 | |
|                     e.printStackTrace();
 | |
|                     return null;
 | |
|                 } finally {
 | |
|                     try {
 | |
|                         gzos.close();
 | |
|                     } catch (Exception e) {
 | |
|                     }
 | |
|                     try {
 | |
|                         b64os.close();
 | |
|                     } catch (Exception e) {
 | |
|                     }
 | |
|                     try {
 | |
|                         baos.close();
 | |
|                     } catch (Exception e) {
 | |
|                     }
 | |
|                 }
 | |
|                 try {
 | |
|                     return new String(baos.toByteArray(), PREFERRED_ENCODING);
 | |
|                 } catch (java.io.UnsupportedEncodingException uue) {
 | |
|                     return new String(baos.toByteArray());
 | |
|                 }
 | |
|             } else {
 | |
|                 boolean breakLines = dontBreakLines == 0;
 | |
|                 int len43 = len * 4 / 3;
 | |
|                 byte[] outBuff = new byte[(len43) + ((len % 3) > 0? 4: 0)
 | |
|                         + (breakLines? (len43 / MAX_LINE_LENGTH): 0)];
 | |
|                 int d = 0;
 | |
|                 int e = 0;
 | |
|                 int len2 = len - 2;
 | |
|                 int lineLength = 0;
 | |
|                 for (; d < len2; d += 3, e += 4) {
 | |
|                     encode3to4(source, d + off, 3, outBuff, e);
 | |
|                     lineLength += 4;
 | |
|                     if (breakLines && lineLength == MAX_LINE_LENGTH) {
 | |
|                         outBuff[e + 4] = NEW_LINE;
 | |
|                         e++;
 | |
|                         lineLength = 0;
 | |
|                     }
 | |
|                 }
 | |
|                 if (d < len) {
 | |
|                     encode3to4(source, d + off, len - d, outBuff, e);
 | |
|                     e += 4;
 | |
|                 }
 | |
|                 try {
 | |
|                     return new String(outBuff, 0, e, PREFERRED_ENCODING);
 | |
|                 } catch (java.io.UnsupportedEncodingException uue) {
 | |
|                     return new String(outBuff, 0, e);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static int decode4to3(byte[] source, int srcOffset, byte[] destination,
 | |
|                 int destOffset) {
 | |
|             if (source[srcOffset + 2] == EQUALS_SIGN) {
 | |
|                 int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
 | |
|                         | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
 | |
|                 destination[destOffset] = (byte)(outBuff >>> 16);
 | |
|                 return 1;
 | |
|             } else if (source[srcOffset + 3] == EQUALS_SIGN) {
 | |
|                 int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
 | |
|                         | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
 | |
|                         | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
 | |
|                 destination[destOffset] = (byte)(outBuff >>> 16);
 | |
|                 destination[destOffset + 1] = (byte)(outBuff >>> 8);
 | |
|                 return 2;
 | |
|             } else {
 | |
|                 try {
 | |
|                     int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
 | |
|                             | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
 | |
|                             | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6)
 | |
|                             | ((DECODABET[source[srcOffset + 3]] & 0xFF));
 | |
|                     destination[destOffset] = (byte)(outBuff >> 16);
 | |
|                     destination[destOffset + 1] = (byte)(outBuff >> 8);
 | |
|                     destination[destOffset + 2] = (byte)(outBuff);
 | |
|                     return 3;
 | |
|                 } catch (Exception e) {
 | |
|                     System.out.println("" + source[srcOffset] + ": "
 | |
|                             + (DECODABET[source[srcOffset]]));
 | |
|                     System.out.println("" + source[srcOffset + 1] + ": "
 | |
|                             + (DECODABET[source[srcOffset + 1]]));
 | |
|                     System.out.println("" + source[srcOffset + 2] + ": "
 | |
|                             + (DECODABET[source[srcOffset + 2]]));
 | |
|                     System.out.println("" + source[srcOffset + 3] + ": "
 | |
|                             + (DECODABET[source[srcOffset + 3]]));
 | |
|                     return -1;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static byte[] decode(byte[] source, int off, int len) {
 | |
|             int len34 = len * 3 / 4;
 | |
|             byte[] outBuff = new byte[len34];
 | |
|             int outBuffPosn = 0;
 | |
|             byte[] b4 = new byte[4];
 | |
|             int b4Posn = 0;
 | |
|             int i = 0;
 | |
|             byte sbiCrop = 0;
 | |
|             byte sbiDecode = 0;
 | |
|             for (i = off; i < off + len; i++) {
 | |
|                 sbiCrop = (byte)(source[i] & 0x7f);
 | |
|                 sbiDecode = DECODABET[sbiCrop];
 | |
|                 if (sbiDecode >= WHITE_SPACE_ENC) {
 | |
|                     if (sbiDecode >= EQUALS_SIGN_ENC) {
 | |
|                         b4[b4Posn++] = sbiCrop;
 | |
|                         if (b4Posn > 3) {
 | |
|                             outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn);
 | |
|                             b4Posn = 0;
 | |
|                             if (sbiCrop == EQUALS_SIGN) break;
 | |
|                         }
 | |
|                     }
 | |
|                 } else {
 | |
|                     throw new IllegalArgumentException("Bad Base64 input character at " + i + ": "
 | |
|                             + source[i] + "(decimal)");
 | |
|                 }
 | |
|             }
 | |
|             byte[] out = new byte[outBuffPosn];
 | |
|             System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
 | |
|             return out;
 | |
|         }
 | |
| 
 | |
|         public static byte[] decode(String s) {
 | |
|             byte[] bytes;
 | |
|             try {
 | |
|                 bytes = s.getBytes(PREFERRED_ENCODING);
 | |
|             } catch (java.io.UnsupportedEncodingException uee) {
 | |
|                 bytes = s.getBytes();
 | |
|             }
 | |
|             bytes = decode(bytes, 0, bytes.length);
 | |
|             if (bytes != null && bytes.length >= 4) {
 | |
|                 int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
 | |
|                 if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) {
 | |
|                     java.io.ByteArrayInputStream bais = null;
 | |
|                     java.util.zip.GZIPInputStream gzis = null;
 | |
|                     java.io.ByteArrayOutputStream baos = null;
 | |
|                     byte[] buffer = new byte[2048];
 | |
|                     int length = 0;
 | |
|                     try {
 | |
|                         baos = new java.io.ByteArrayOutputStream();
 | |
|                         bais = new java.io.ByteArrayInputStream(bytes);
 | |
|                         gzis = new java.util.zip.GZIPInputStream(bais);
 | |
|                         while ((length = gzis.read(buffer)) >= 0) {
 | |
|                             baos.write(buffer, 0, length);
 | |
|                         }
 | |
|                         bytes = baos.toByteArray();
 | |
|                     } catch (java.io.IOException e) {
 | |
|                     } finally {
 | |
|                         try {
 | |
|                             baos.close();
 | |
|                         } catch (Exception e) {
 | |
|                         }
 | |
|                         try {
 | |
|                             gzis.close();
 | |
|                         } catch (Exception e) {
 | |
|                         }
 | |
|                         try {
 | |
|                             bais.close();
 | |
|                         } catch (Exception e) {
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return bytes;
 | |
|         }
 | |
| 
 | |
|         public static Object decodeToObject(String encodedObject) {
 | |
|             byte[] objBytes = decode(encodedObject);
 | |
|             java.io.ByteArrayInputStream bais = null;
 | |
|             java.io.ObjectInputStream ois = null;
 | |
|             Object obj = null;
 | |
|             try {
 | |
|                 bais = new java.io.ByteArrayInputStream(objBytes);
 | |
|                 ois = new java.io.ObjectInputStream(bais);
 | |
|                 obj = ois.readObject();
 | |
|             } catch (java.io.IOException e) {
 | |
|                 e.printStackTrace();
 | |
|                 obj = null;
 | |
|             } catch (java.lang.ClassNotFoundException e) {
 | |
|                 e.printStackTrace();
 | |
|                 obj = null;
 | |
|             } finally {
 | |
|                 try {
 | |
|                     bais.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|                 try {
 | |
|                     ois.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             return obj;
 | |
|         }
 | |
| 
 | |
|         public static boolean encodeToFile(byte[] dataToEncode, String filename) {
 | |
|             boolean success = false;
 | |
|             Base64.OutputStream bos = null;
 | |
|             try {
 | |
|                 bos = new Base64.OutputStream(new java.io.FileOutputStream(filename), Base64.ENCODE);
 | |
|                 bos.write(dataToEncode);
 | |
|                 success = true;
 | |
|             } catch (java.io.IOException e) {
 | |
|                 success = false;
 | |
|             } finally {
 | |
|                 try {
 | |
|                     bos.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             return success;
 | |
|         }
 | |
| 
 | |
|         public static boolean decodeToFile(String dataToDecode, String filename) {
 | |
|             boolean success = false;
 | |
|             Base64.OutputStream bos = null;
 | |
|             try {
 | |
|                 bos = new Base64.OutputStream(new java.io.FileOutputStream(filename), Base64.DECODE);
 | |
|                 bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
 | |
|                 success = true;
 | |
|             } catch (java.io.IOException e) {
 | |
|                 success = false;
 | |
|             } finally {
 | |
|                 try {
 | |
|                     bos.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             return success;
 | |
|         }
 | |
| 
 | |
|         public static byte[] decodeFromFile(String filename) {
 | |
|             byte[] decodedData = null;
 | |
|             Base64.InputStream bis = null;
 | |
|             try {
 | |
|                 java.io.File file = new java.io.File(filename);
 | |
|                 byte[] buffer = null;
 | |
|                 int length = 0;
 | |
|                 int numBytes = 0;
 | |
|                 if (file.length() > Integer.MAX_VALUE) {
 | |
|                     throw new IllegalArgumentException(
 | |
|                             "File is too big for this convenience method (" + file.length()
 | |
|                                     + " bytes).");
 | |
|                 }
 | |
|                 buffer = new byte[(int)file.length()];
 | |
|                 bis = new Base64.InputStream(new java.io.BufferedInputStream(
 | |
|                         new java.io.FileInputStream(file)), Base64.DECODE);
 | |
|                 while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
 | |
|                     length += numBytes;
 | |
|                 decodedData = new byte[length];
 | |
|                 System.arraycopy(buffer, 0, decodedData, 0, length);
 | |
|             } catch (java.io.IOException e) {
 | |
|                 throw new IllegalArgumentException("Error decoding from file " + filename);
 | |
|             } finally {
 | |
|                 try {
 | |
|                     bis.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             return decodedData;
 | |
|         }
 | |
| 
 | |
|         public static String encodeFromFile(String filename) {
 | |
|             String encodedData = null;
 | |
|             Base64.InputStream bis = null;
 | |
|             try {
 | |
|                 java.io.File file = new java.io.File(filename);
 | |
|                 byte[] buffer = new byte[(int)(file.length() * 1.4)];
 | |
|                 int length = 0;
 | |
|                 int numBytes = 0;
 | |
|                 bis = new Base64.InputStream(new java.io.BufferedInputStream(
 | |
|                         new java.io.FileInputStream(file)), Base64.ENCODE);
 | |
|                 while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
 | |
|                     length += numBytes;
 | |
|                 encodedData = new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
 | |
|             } catch (java.io.IOException e) {
 | |
|                 System.err.println("Error encoding from file " + filename);
 | |
|             } finally {
 | |
|                 try {
 | |
|                     bis.close();
 | |
|                 } catch (Exception e) {
 | |
|                 }
 | |
|             }
 | |
|             return encodedData;
 | |
|         }
 | |
| 
 | |
|         public static class InputStream extends java.io.FilterInputStream {
 | |
|             private boolean encode;
 | |
| 
 | |
|             private int position;
 | |
| 
 | |
|             private byte[] buffer;
 | |
| 
 | |
|             private int bufferLength;
 | |
| 
 | |
|             private int numSigBytes;
 | |
| 
 | |
|             private int lineLength;
 | |
| 
 | |
|             private boolean breakLines;
 | |
| 
 | |
|             public InputStream(java.io.InputStream in) {
 | |
|                 this(in, DECODE);
 | |
|             }
 | |
| 
 | |
|             public InputStream(java.io.InputStream in, int options) {
 | |
|                 super(in);
 | |
|                 this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
 | |
|                 this.encode = (options & ENCODE) == ENCODE;
 | |
|                 this.bufferLength = encode? 4: 3;
 | |
|                 this.buffer = new byte[bufferLength];
 | |
|                 this.position = -1;
 | |
|                 this.lineLength = 0;
 | |
|             }
 | |
| 
 | |
|             public int read() throws java.io.IOException {
 | |
|                 if (position < 0) {
 | |
|                     if (encode) {
 | |
|                         byte[] b3 = new byte[3];
 | |
|                         int numBinaryBytes = 0;
 | |
|                         for (int i = 0; i < 3; i++) {
 | |
|                             try {
 | |
|                                 int b = in.read();
 | |
|                                 if (b >= 0) {
 | |
|                                     b3[i] = (byte)b;
 | |
|                                     numBinaryBytes++;
 | |
|                                 }
 | |
|                             } catch (java.io.IOException e) {
 | |
|                                 if (i == 0) throw e;
 | |
|                             }
 | |
|                         }
 | |
|                         if (numBinaryBytes > 0) {
 | |
|                             encode3to4(b3, 0, numBinaryBytes, buffer, 0);
 | |
|                             position = 0;
 | |
|                             numSigBytes = 4;
 | |
|                         } else {
 | |
|                             return -1;
 | |
|                         }
 | |
|                     } else {
 | |
|                         byte[] b4 = new byte[4];
 | |
|                         int i = 0;
 | |
|                         for (i = 0; i < 4; i++) {
 | |
|                             int b = 0;
 | |
|                             do {
 | |
|                                 b = in.read();
 | |
|                             } while (b >= 0 && DECODABET[b & 0x7f] <= WHITE_SPACE_ENC);
 | |
|                             if (b < 0) break;
 | |
|                             b4[i] = (byte)b;
 | |
|                         }
 | |
|                         if (i == 4) {
 | |
|                             numSigBytes = decode4to3(b4, 0, buffer, 0);
 | |
|                             position = 0;
 | |
|                         } else if (i == 0) {
 | |
|                             return -1;
 | |
|                         } else {
 | |
|                             throw new java.io.IOException("Improperly padded Base64 input.");
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 if (position >= 0) {
 | |
|                     if ( /* !encode && */position >= numSigBytes) return -1;
 | |
|                     if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) {
 | |
|                         lineLength = 0;
 | |
|                         return '\n';
 | |
|                     } else {
 | |
|                         lineLength++;
 | |
|                         int b = buffer[position++];
 | |
|                         if (position >= bufferLength) position = -1;
 | |
|                         return b & 0xFF;
 | |
|                     }
 | |
|                 } else {
 | |
|                     throw new java.io.IOException("Error in Base64 code reading stream.");
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public int read(byte[] dest, int off, int len) throws java.io.IOException {
 | |
|                 int i;
 | |
|                 int b;
 | |
|                 for (i = 0; i < len; i++) {
 | |
|                     b = read();
 | |
|                     if (b >= 0) dest[off + i] = (byte)b;
 | |
|                     else if (i == 0) return -1;
 | |
|                     else break;
 | |
|                 }
 | |
|                 return i;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static class OutputStream extends java.io.FilterOutputStream {
 | |
|             private boolean encode;
 | |
| 
 | |
|             private int position;
 | |
| 
 | |
|             private byte[] buffer;
 | |
| 
 | |
|             private int bufferLength;
 | |
| 
 | |
|             private int lineLength;
 | |
| 
 | |
|             private boolean breakLines;
 | |
| 
 | |
|             private byte[] b4;
 | |
| 
 | |
|             private boolean suspendEncoding;
 | |
| 
 | |
|             public OutputStream(java.io.OutputStream out) {
 | |
|                 this(out, ENCODE);
 | |
|             }
 | |
| 
 | |
|             public OutputStream(java.io.OutputStream out, int options) {
 | |
|                 super(out);
 | |
|                 this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
 | |
|                 this.encode = (options & ENCODE) == ENCODE;
 | |
|                 this.bufferLength = encode? 3: 4;
 | |
|                 this.buffer = new byte[bufferLength];
 | |
|                 this.position = 0;
 | |
|                 this.lineLength = 0;
 | |
|                 this.suspendEncoding = false;
 | |
|                 this.b4 = new byte[4];
 | |
|             }
 | |
| 
 | |
|             public void write(int theByte) throws java.io.IOException {
 | |
|                 if (suspendEncoding) {
 | |
|                     super.out.write(theByte);
 | |
|                     return;
 | |
|                 }
 | |
|                 if (encode) {
 | |
|                     buffer[position++] = (byte)theByte;
 | |
|                     if (position >= bufferLength) {
 | |
|                         out.write(encode3to4(b4, buffer, bufferLength));
 | |
|                         lineLength += 4;
 | |
|                         if (breakLines && lineLength >= MAX_LINE_LENGTH) {
 | |
|                             out.write(NEW_LINE);
 | |
|                             lineLength = 0;
 | |
|                         }
 | |
|                         position = 0;
 | |
|                     }
 | |
|                 } else {
 | |
|                     if (DECODABET[theByte & 0x7f] > WHITE_SPACE_ENC) {
 | |
|                         buffer[position++] = (byte)theByte;
 | |
|                         if (position >= bufferLength) {
 | |
|                             int len = Base64.decode4to3(buffer, 0, b4, 0);
 | |
|                             out.write(b4, 0, len);
 | |
|                             position = 0;
 | |
|                         }
 | |
|                     } else if (DECODABET[theByte & 0x7f] != WHITE_SPACE_ENC) {
 | |
|                         throw new java.io.IOException("Invalid character in Base64 data.");
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public void write(byte[] theBytes, int off, int len) throws java.io.IOException {
 | |
|                 if (suspendEncoding) {
 | |
|                     super.out.write(theBytes, off, len);
 | |
|                     return;
 | |
|                 }
 | |
|                 for (int i = 0; i < len; i++) {
 | |
|                     write(theBytes[off + i]);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public void flushBase64() throws java.io.IOException {
 | |
|                 if (position > 0) {
 | |
|                     if (encode) {
 | |
|                         out.write(encode3to4(b4, buffer, position));
 | |
|                         position = 0;
 | |
|                     } else {
 | |
|                         throw new java.io.IOException("Base64 input not properly padded.");
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public void close() throws java.io.IOException {
 | |
|                 flushBase64();
 | |
|                 super.close();
 | |
|                 buffer = null;
 | |
|                 out = null;
 | |
|             }
 | |
| 
 | |
|             public void suspendEncoding() throws java.io.IOException {
 | |
|                 flushBase64();
 | |
|                 this.suspendEncoding = true;
 | |
|             }
 | |
| 
 | |
|             public void resumeEncoding() {
 | |
|                 this.suspendEncoding = false;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class DES {
 | |
|         private int[] encryptKeys = new int[32];
 | |
| 
 | |
|         private int[] decryptKeys = new int[32];
 | |
| 
 | |
|         private int[] tempInts = new int[2];
 | |
| 
 | |
|         public DES() {
 | |
|         }
 | |
| 
 | |
|         public DES(byte[] key) {
 | |
|             if (key.length == 7) {
 | |
|                 byte[] key8 = new byte[8];
 | |
|                 makeSMBKey(key, key8);
 | |
|                 setKey(key8);
 | |
|             } else {
 | |
|                 setKey(key);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static void makeSMBKey(byte[] key7, byte[] key8) {
 | |
|             int i;
 | |
|             key8[0] = (byte)((key7[0] >> 1) & 0xff);
 | |
|             key8[1] = (byte)((((key7[0] & 0x01) << 6) | (((key7[1] & 0xff) >> 2) & 0xff)) & 0xff);
 | |
|             key8[2] = (byte)((((key7[1] & 0x03) << 5) | (((key7[2] & 0xff) >> 3) & 0xff)) & 0xff);
 | |
|             key8[3] = (byte)((((key7[2] & 0x07) << 4) | (((key7[3] & 0xff) >> 4) & 0xff)) & 0xff);
 | |
|             key8[4] = (byte)((((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff) >> 5) & 0xff)) & 0xff);
 | |
|             key8[5] = (byte)((((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff) >> 6) & 0xff)) & 0xff);
 | |
|             key8[6] = (byte)((((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff) >> 7) & 0xff)) & 0xff);
 | |
|             key8[7] = (byte)(key7[6] & 0x7F);
 | |
|             for (i = 0; i < 8; i++) {
 | |
|                 key8[i] = (byte)(key8[i] << 1);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void setKey(byte[] key) {
 | |
|             deskey(key, true, encryptKeys);
 | |
|             deskey(key, false, decryptKeys);
 | |
|         }
 | |
| 
 | |
|         private void deskey(byte[] keyBlock, boolean encrypting, int[] KnL) {
 | |
|             int i, j, l, m, n;
 | |
|             int[] pc1m = new int[56];
 | |
|             int[] pcr = new int[56];
 | |
|             int[] kn = new int[32];
 | |
|             for (j = 0; j < 56; ++j) {
 | |
|                 l = pc1[j];
 | |
|                 m = l & 07;
 | |
|                 pc1m[j] = ((keyBlock[l >>> 3] & bytebit[m]) != 0)? 1: 0;
 | |
|             }
 | |
|             for (i = 0; i < 16; ++i) {
 | |
|                 if (encrypting) m = i << 1;
 | |
|                 else m = (15 - i) << 1;
 | |
|                 n = m + 1;
 | |
|                 kn[m] = kn[n] = 0;
 | |
|                 for (j = 0; j < 28; ++j) {
 | |
|                     l = j + totrot[i];
 | |
|                     if (l < 28) pcr[j] = pc1m[l];
 | |
|                     else pcr[j] = pc1m[l - 28];
 | |
|                 }
 | |
|                 for (j = 28; j < 56; ++j) {
 | |
|                     l = j + totrot[i];
 | |
|                     if (l < 56) pcr[j] = pc1m[l];
 | |
|                     else pcr[j] = pc1m[l - 28];
 | |
|                 }
 | |
|                 for (j = 0; j < 24; ++j) {
 | |
|                     if (pcr[pc2[j]] != 0) kn[m] |= bigbyte[j];
 | |
|                     if (pcr[pc2[j + 24]] != 0) kn[n] |= bigbyte[j];
 | |
|                 }
 | |
|             }
 | |
|             cookey(kn, KnL);
 | |
|         }
 | |
| 
 | |
|         private void cookey(int[] raw, int KnL[]) {
 | |
|             int raw0, raw1;
 | |
|             int rawi, KnLi;
 | |
|             int i;
 | |
|             for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
 | |
|                 raw0 = raw[rawi++];
 | |
|                 raw1 = raw[rawi++];
 | |
|                 KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
 | |
|                 KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
 | |
|                 KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
 | |
|                 KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
 | |
|                 ++KnLi;
 | |
|                 KnL[KnLi] = (raw0 & 0x0003f000) << 12;
 | |
|                 KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
 | |
|                 KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
 | |
|                 KnL[KnLi] |= (raw1 & 0x0000003f);
 | |
|                 ++KnLi;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void encrypt(byte[] clearText, int clearOff, byte[] cipherText, int cipherOff) {
 | |
|             squashBytesToInts(clearText, clearOff, tempInts, 0, 2);
 | |
|             des(tempInts, tempInts, encryptKeys);
 | |
|             spreadIntsToBytes(tempInts, 0, cipherText, cipherOff, 2);
 | |
|         }
 | |
| 
 | |
|         private void decrypt(byte[] cipherText, int cipherOff, byte[] clearText, int clearOff) {
 | |
|             squashBytesToInts(cipherText, cipherOff, tempInts, 0, 2);
 | |
|             des(tempInts, tempInts, decryptKeys);
 | |
|             spreadIntsToBytes(tempInts, 0, clearText, clearOff, 2);
 | |
|         }
 | |
| 
 | |
|         private void des(int[] inInts, int[] outInts, int[] keys) {
 | |
|             int fval, work, right, leftt;
 | |
|             int round;
 | |
|             int keysi = 0;
 | |
|             leftt = inInts[0];
 | |
|             right = inInts[1];
 | |
|             work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
 | |
|             right ^= work;
 | |
|             leftt ^= (work << 4);
 | |
|             work = ((leftt >>> 16) ^ right) & 0x0000ffff;
 | |
|             right ^= work;
 | |
|             leftt ^= (work << 16);
 | |
|             work = ((right >>> 2) ^ leftt) & 0x33333333;
 | |
|             leftt ^= work;
 | |
|             right ^= (work << 2);
 | |
|             work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
 | |
|             leftt ^= work;
 | |
|             right ^= (work << 8);
 | |
|             right = (right << 1) | ((right >>> 31) & 1);
 | |
|             work = (leftt ^ right) & 0xaaaaaaaa;
 | |
|             leftt ^= work;
 | |
|             right ^= work;
 | |
|             leftt = (leftt << 1) | ((leftt >>> 31) & 1);
 | |
|             for (round = 0; round < 8; ++round) {
 | |
|                 work = (right << 28) | (right >>> 4);
 | |
|                 work ^= keys[keysi++];
 | |
|                 fval = SP7[work & 0x0000003f];
 | |
|                 fval |= SP5[(work >>> 8) & 0x0000003f];
 | |
|                 fval |= SP3[(work >>> 16) & 0x0000003f];
 | |
|                 fval |= SP1[(work >>> 24) & 0x0000003f];
 | |
|                 work = right ^ keys[keysi++];
 | |
|                 fval |= SP8[work & 0x0000003f];
 | |
|                 fval |= SP6[(work >>> 8) & 0x0000003f];
 | |
|                 fval |= SP4[(work >>> 16) & 0x0000003f];
 | |
|                 fval |= SP2[(work >>> 24) & 0x0000003f];
 | |
|                 leftt ^= fval;
 | |
|                 work = (leftt << 28) | (leftt >>> 4);
 | |
|                 work ^= keys[keysi++];
 | |
|                 fval = SP7[work & 0x0000003f];
 | |
|                 fval |= SP5[(work >>> 8) & 0x0000003f];
 | |
|                 fval |= SP3[(work >>> 16) & 0x0000003f];
 | |
|                 fval |= SP1[(work >>> 24) & 0x0000003f];
 | |
|                 work = leftt ^ keys[keysi++];
 | |
|                 fval |= SP8[work & 0x0000003f];
 | |
|                 fval |= SP6[(work >>> 8) & 0x0000003f];
 | |
|                 fval |= SP4[(work >>> 16) & 0x0000003f];
 | |
|                 fval |= SP2[(work >>> 24) & 0x0000003f];
 | |
|                 right ^= fval;
 | |
|             }
 | |
|             right = (right << 31) | (right >>> 1);
 | |
|             work = (leftt ^ right) & 0xaaaaaaaa;
 | |
|             leftt ^= work;
 | |
|             right ^= work;
 | |
|             leftt = (leftt << 31) | (leftt >>> 1);
 | |
|             work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
 | |
|             right ^= work;
 | |
|             leftt ^= (work << 8);
 | |
|             work = ((leftt >>> 2) ^ right) & 0x33333333;
 | |
|             right ^= work;
 | |
|             leftt ^= (work << 2);
 | |
|             work = ((right >>> 16) ^ leftt) & 0x0000ffff;
 | |
|             leftt ^= work;
 | |
|             right ^= (work << 16);
 | |
|             work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
 | |
|             leftt ^= work;
 | |
|             right ^= (work << 4);
 | |
|             outInts[0] = right;
 | |
|             outInts[1] = leftt;
 | |
|         }
 | |
| 
 | |
|         public void encrypt(byte[] clearText, byte[] cipherText) {
 | |
|             encrypt(clearText, 0, cipherText, 0);
 | |
|         }
 | |
| 
 | |
|         public void decrypt(byte[] cipherText, byte[] clearText) {
 | |
|             decrypt(cipherText, 0, clearText, 0);
 | |
|         }
 | |
| 
 | |
|         public byte[] encrypt(byte[] clearText) {
 | |
|             int length = clearText.length;
 | |
|             if (length % 8 != 0) {
 | |
|                 System.out.println("Array must be a multiple of 8");
 | |
|                 return null;
 | |
|             }
 | |
|             byte[] cipherText = new byte[length];
 | |
|             int count = length / 8;
 | |
|             for (int i = 0; i < count; i++)
 | |
|                 encrypt(clearText, i * 8, cipherText, i * 8);
 | |
|             return cipherText;
 | |
|         }
 | |
| 
 | |
|         public byte[] decrypt(byte[] cipherText) {
 | |
|             int length = cipherText.length;
 | |
|             if (length % 8 != 0) {
 | |
|                 System.out.println("Array must be a multiple of 8");
 | |
|                 return null;
 | |
|             }
 | |
|             byte[] clearText = new byte[length];
 | |
|             int count = length / 8;
 | |
|             for (int i = 0; i < count; i++)
 | |
|                 encrypt(cipherText, i * 8, clearText, i * 8);
 | |
|             return clearText;
 | |
|         }
 | |
| 
 | |
|         private static byte[] bytebit = {
 | |
|                 (byte)0x80,
 | |
|                 (byte)0x40,
 | |
|                 (byte)0x20,
 | |
|                 (byte)0x10,
 | |
|                 (byte)0x08,
 | |
|                 (byte)0x04,
 | |
|                 (byte)0x02,
 | |
|                 (byte)0x01};
 | |
| 
 | |
|         private static int[] bigbyte = {
 | |
|                 0x800000,
 | |
|                 0x400000,
 | |
|                 0x200000,
 | |
|                 0x100000,
 | |
|                 0x080000,
 | |
|                 0x040000,
 | |
|                 0x020000,
 | |
|                 0x010000,
 | |
|                 0x008000,
 | |
|                 0x004000,
 | |
|                 0x002000,
 | |
|                 0x001000,
 | |
|                 0x000800,
 | |
|                 0x000400,
 | |
|                 0x000200,
 | |
|                 0x000100,
 | |
|                 0x000080,
 | |
|                 0x000040,
 | |
|                 0x000020,
 | |
|                 0x000010,
 | |
|                 0x000008,
 | |
|                 0x000004,
 | |
|                 0x000002,
 | |
|                 0x000001};
 | |
| 
 | |
|         private static byte[] pc1 = {
 | |
|                 (byte)56,
 | |
|                 (byte)48,
 | |
|                 (byte)40,
 | |
|                 (byte)32,
 | |
|                 (byte)24,
 | |
|                 (byte)16,
 | |
|                 (byte)8,
 | |
|                 (byte)0,
 | |
|                 (byte)57,
 | |
|                 (byte)49,
 | |
|                 (byte)41,
 | |
|                 (byte)33,
 | |
|                 (byte)25,
 | |
|                 (byte)17,
 | |
|                 (byte)9,
 | |
|                 (byte)1,
 | |
|                 (byte)58,
 | |
|                 (byte)50,
 | |
|                 (byte)42,
 | |
|                 (byte)34,
 | |
|                 (byte)26,
 | |
|                 (byte)18,
 | |
|                 (byte)10,
 | |
|                 (byte)2,
 | |
|                 (byte)59,
 | |
|                 (byte)51,
 | |
|                 (byte)43,
 | |
|                 (byte)35,
 | |
|                 (byte)62,
 | |
|                 (byte)54,
 | |
|                 (byte)46,
 | |
|                 (byte)38,
 | |
|                 (byte)30,
 | |
|                 (byte)22,
 | |
|                 (byte)14,
 | |
|                 (byte)6,
 | |
|                 (byte)61,
 | |
|                 (byte)53,
 | |
|                 (byte)45,
 | |
|                 (byte)37,
 | |
|                 (byte)29,
 | |
|                 (byte)21,
 | |
|                 (byte)13,
 | |
|                 (byte)5,
 | |
|                 (byte)60,
 | |
|                 (byte)52,
 | |
|                 (byte)44,
 | |
|                 (byte)36,
 | |
|                 (byte)28,
 | |
|                 (byte)20,
 | |
|                 (byte)12,
 | |
|                 (byte)4,
 | |
|                 (byte)27,
 | |
|                 (byte)19,
 | |
|                 (byte)11,
 | |
|                 (byte)3};
 | |
| 
 | |
|         private static int[] totrot = {1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};
 | |
| 
 | |
|         private static byte[] pc2 = {
 | |
|                 (byte)13,
 | |
|                 (byte)16,
 | |
|                 (byte)10,
 | |
|                 (byte)23,
 | |
|                 (byte)0,
 | |
|                 (byte)4,
 | |
|                 (byte)2,
 | |
|                 (byte)27,
 | |
|                 (byte)14,
 | |
|                 (byte)5,
 | |
|                 (byte)20,
 | |
|                 (byte)9,
 | |
|                 (byte)22,
 | |
|                 (byte)18,
 | |
|                 (byte)11,
 | |
|                 (byte)3,
 | |
|                 (byte)25,
 | |
|                 (byte)7,
 | |
|                 (byte)15,
 | |
|                 (byte)6,
 | |
|                 (byte)26,
 | |
|                 (byte)19,
 | |
|                 (byte)12,
 | |
|                 (byte)1,
 | |
|                 (byte)40,
 | |
|                 (byte)51,
 | |
|                 (byte)30,
 | |
|                 (byte)36,
 | |
|                 (byte)46,
 | |
|                 (byte)54,
 | |
|                 (byte)29,
 | |
|                 (byte)39,
 | |
|                 (byte)50,
 | |
|                 (byte)44,
 | |
|                 (byte)32,
 | |
|                 (byte)47,
 | |
|                 (byte)43,
 | |
|                 (byte)48,
 | |
|                 (byte)38,
 | |
|                 (byte)55,
 | |
|                 (byte)33,
 | |
|                 (byte)52,
 | |
|                 (byte)45,
 | |
|                 (byte)41,
 | |
|                 (byte)49,
 | |
|                 (byte)35,
 | |
|                 (byte)28,
 | |
|                 (byte)31,};
 | |
| 
 | |
|         private static int[] SP1 = {
 | |
|                 0x01010400,
 | |
|                 0x00000000,
 | |
|                 0x00010000,
 | |
|                 0x01010404,
 | |
|                 0x01010004,
 | |
|                 0x00010404,
 | |
|                 0x00000004,
 | |
|                 0x00010000,
 | |
|                 0x00000400,
 | |
|                 0x01010400,
 | |
|                 0x01010404,
 | |
|                 0x00000400,
 | |
|                 0x01000404,
 | |
|                 0x01010004,
 | |
|                 0x01000000,
 | |
|                 0x00000004,
 | |
|                 0x00000404,
 | |
|                 0x01000400,
 | |
|                 0x01000400,
 | |
|                 0x00010400,
 | |
|                 0x00010400,
 | |
|                 0x01010000,
 | |
|                 0x01010000,
 | |
|                 0x01000404,
 | |
|                 0x00010004,
 | |
|                 0x01000004,
 | |
|                 0x01000004,
 | |
|                 0x00010004,
 | |
|                 0x00000000,
 | |
|                 0x00000404,
 | |
|                 0x00010404,
 | |
|                 0x01000000,
 | |
|                 0x00010000,
 | |
|                 0x01010404,
 | |
|                 0x00000004,
 | |
|                 0x01010000,
 | |
|                 0x01010400,
 | |
|                 0x01000000,
 | |
|                 0x01000000,
 | |
|                 0x00000400,
 | |
|                 0x01010004,
 | |
|                 0x00010000,
 | |
|                 0x00010400,
 | |
|                 0x01000004,
 | |
|                 0x00000400,
 | |
|                 0x00000004,
 | |
|                 0x01000404,
 | |
|                 0x00010404,
 | |
|                 0x01010404,
 | |
|                 0x00010004,
 | |
|                 0x01010000,
 | |
|                 0x01000404,
 | |
|                 0x01000004,
 | |
|                 0x00000404,
 | |
|                 0x00010404,
 | |
|                 0x01010400,
 | |
|                 0x00000404,
 | |
|                 0x01000400,
 | |
|                 0x01000400,
 | |
|                 0x00000000,
 | |
|                 0x00010004,
 | |
|                 0x00010400,
 | |
|                 0x00000000,
 | |
|                 0x01010004};
 | |
| 
 | |
|         private static int[] SP2 = {
 | |
|                 0x80108020,
 | |
|                 0x80008000,
 | |
|                 0x00008000,
 | |
|                 0x00108020,
 | |
|                 0x00100000,
 | |
|                 0x00000020,
 | |
|                 0x80100020,
 | |
|                 0x80008020,
 | |
|                 0x80000020,
 | |
|                 0x80108020,
 | |
|                 0x80108000,
 | |
|                 0x80000000,
 | |
|                 0x80008000,
 | |
|                 0x00100000,
 | |
|                 0x00000020,
 | |
|                 0x80100020,
 | |
|                 0x00108000,
 | |
|                 0x00100020,
 | |
|                 0x80008020,
 | |
|                 0x00000000,
 | |
|                 0x80000000,
 | |
|                 0x00008000,
 | |
|                 0x00108020,
 | |
|                 0x80100000,
 | |
|                 0x00100020,
 | |
|                 0x80000020,
 | |
|                 0x00000000,
 | |
|                 0x00108000,
 | |
|                 0x00008020,
 | |
|                 0x80108000,
 | |
|                 0x80100000,
 | |
|                 0x00008020,
 | |
|                 0x00000000,
 | |
|                 0x00108020,
 | |
|                 0x80100020,
 | |
|                 0x00100000,
 | |
|                 0x80008020,
 | |
|                 0x80100000,
 | |
|                 0x80108000,
 | |
|                 0x00008000,
 | |
|                 0x80100000,
 | |
|                 0x80008000,
 | |
|                 0x00000020,
 | |
|                 0x80108020,
 | |
|                 0x00108020,
 | |
|                 0x00000020,
 | |
|                 0x00008000,
 | |
|                 0x80000000,
 | |
|                 0x00008020,
 | |
|                 0x80108000,
 | |
|                 0x00100000,
 | |
|                 0x80000020,
 | |
|                 0x00100020,
 | |
|                 0x80008020,
 | |
|                 0x80000020,
 | |
|                 0x00100020,
 | |
|                 0x00108000,
 | |
|                 0x00000000,
 | |
|                 0x80008000,
 | |
|                 0x00008020,
 | |
|                 0x80000000,
 | |
|                 0x80100020,
 | |
|                 0x80108020,
 | |
|                 0x00108000};
 | |
| 
 | |
|         private static int[] SP3 = {
 | |
|                 0x00000208,
 | |
|                 0x08020200,
 | |
|                 0x00000000,
 | |
|                 0x08020008,
 | |
|                 0x08000200,
 | |
|                 0x00000000,
 | |
|                 0x00020208,
 | |
|                 0x08000200,
 | |
|                 0x00020008,
 | |
|                 0x08000008,
 | |
|                 0x08000008,
 | |
|                 0x00020000,
 | |
|                 0x08020208,
 | |
|                 0x00020008,
 | |
|                 0x08020000,
 | |
|                 0x00000208,
 | |
|                 0x08000000,
 | |
|                 0x00000008,
 | |
|                 0x08020200,
 | |
|                 0x00000200,
 | |
|                 0x00020200,
 | |
|                 0x08020000,
 | |
|                 0x08020008,
 | |
|                 0x00020208,
 | |
|                 0x08000208,
 | |
|                 0x00020200,
 | |
|                 0x00020000,
 | |
|                 0x08000208,
 | |
|                 0x00000008,
 | |
|                 0x08020208,
 | |
|                 0x00000200,
 | |
|                 0x08000000,
 | |
|                 0x08020200,
 | |
|                 0x08000000,
 | |
|                 0x00020008,
 | |
|                 0x00000208,
 | |
|                 0x00020000,
 | |
|                 0x08020200,
 | |
|                 0x08000200,
 | |
|                 0x00000000,
 | |
|                 0x00000200,
 | |
|                 0x00020008,
 | |
|                 0x08020208,
 | |
|                 0x08000200,
 | |
|                 0x08000008,
 | |
|                 0x00000200,
 | |
|                 0x00000000,
 | |
|                 0x08020008,
 | |
|                 0x08000208,
 | |
|                 0x00020000,
 | |
|                 0x08000000,
 | |
|                 0x08020208,
 | |
|                 0x00000008,
 | |
|                 0x00020208,
 | |
|                 0x00020200,
 | |
|                 0x08000008,
 | |
|                 0x08020000,
 | |
|                 0x08000208,
 | |
|                 0x00000208,
 | |
|                 0x08020000,
 | |
|                 0x00020208,
 | |
|                 0x00000008,
 | |
|                 0x08020008,
 | |
|                 0x00020200};
 | |
| 
 | |
|         private static int[] SP4 = {
 | |
|                 0x00802001,
 | |
|                 0x00002081,
 | |
|                 0x00002081,
 | |
|                 0x00000080,
 | |
|                 0x00802080,
 | |
|                 0x00800081,
 | |
|                 0x00800001,
 | |
|                 0x00002001,
 | |
|                 0x00000000,
 | |
|                 0x00802000,
 | |
|                 0x00802000,
 | |
|                 0x00802081,
 | |
|                 0x00000081,
 | |
|                 0x00000000,
 | |
|                 0x00800080,
 | |
|                 0x00800001,
 | |
|                 0x00000001,
 | |
|                 0x00002000,
 | |
|                 0x00800000,
 | |
|                 0x00802001,
 | |
|                 0x00000080,
 | |
|                 0x00800000,
 | |
|                 0x00002001,
 | |
|                 0x00002080,
 | |
|                 0x00800081,
 | |
|                 0x00000001,
 | |
|                 0x00002080,
 | |
|                 0x00800080,
 | |
|                 0x00002000,
 | |
|                 0x00802080,
 | |
|                 0x00802081,
 | |
|                 0x00000081,
 | |
|                 0x00800080,
 | |
|                 0x00800001,
 | |
|                 0x00802000,
 | |
|                 0x00802081,
 | |
|                 0x00000081,
 | |
|                 0x00000000,
 | |
|                 0x00000000,
 | |
|                 0x00802000,
 | |
|                 0x00002080,
 | |
|                 0x00800080,
 | |
|                 0x00800081,
 | |
|                 0x00000001,
 | |
|                 0x00802001,
 | |
|                 0x00002081,
 | |
|                 0x00002081,
 | |
|                 0x00000080,
 | |
|                 0x00802081,
 | |
|                 0x00000081,
 | |
|                 0x00000001,
 | |
|                 0x00002000,
 | |
|                 0x00800001,
 | |
|                 0x00002001,
 | |
|                 0x00802080,
 | |
|                 0x00800081,
 | |
|                 0x00002001,
 | |
|                 0x00002080,
 | |
|                 0x00800000,
 | |
|                 0x00802001,
 | |
|                 0x00000080,
 | |
|                 0x00800000,
 | |
|                 0x00002000,
 | |
|                 0x00802080};
 | |
| 
 | |
|         private static int[] SP5 = {
 | |
|                 0x00000100,
 | |
|                 0x02080100,
 | |
|                 0x02080000,
 | |
|                 0x42000100,
 | |
|                 0x00080000,
 | |
|                 0x00000100,
 | |
|                 0x40000000,
 | |
|                 0x02080000,
 | |
|                 0x40080100,
 | |
|                 0x00080000,
 | |
|                 0x02000100,
 | |
|                 0x40080100,
 | |
|                 0x42000100,
 | |
|                 0x42080000,
 | |
|                 0x00080100,
 | |
|                 0x40000000,
 | |
|                 0x02000000,
 | |
|                 0x40080000,
 | |
|                 0x40080000,
 | |
|                 0x00000000,
 | |
|                 0x40000100,
 | |
|                 0x42080100,
 | |
|                 0x42080100,
 | |
|                 0x02000100,
 | |
|                 0x42080000,
 | |
|                 0x40000100,
 | |
|                 0x00000000,
 | |
|                 0x42000000,
 | |
|                 0x02080100,
 | |
|                 0x02000000,
 | |
|                 0x42000000,
 | |
|                 0x00080100,
 | |
|                 0x00080000,
 | |
|                 0x42000100,
 | |
|                 0x00000100,
 | |
|                 0x02000000,
 | |
|                 0x40000000,
 | |
|                 0x02080000,
 | |
|                 0x42000100,
 | |
|                 0x40080100,
 | |
|                 0x02000100,
 | |
|                 0x40000000,
 | |
|                 0x42080000,
 | |
|                 0x02080100,
 | |
|                 0x40080100,
 | |
|                 0x00000100,
 | |
|                 0x02000000,
 | |
|                 0x42080000,
 | |
|                 0x42080100,
 | |
|                 0x00080100,
 | |
|                 0x42000000,
 | |
|                 0x42080100,
 | |
|                 0x02080000,
 | |
|                 0x00000000,
 | |
|                 0x40080000,
 | |
|                 0x42000000,
 | |
|                 0x00080100,
 | |
|                 0x02000100,
 | |
|                 0x40000100,
 | |
|                 0x00080000,
 | |
|                 0x00000000,
 | |
|                 0x40080000,
 | |
|                 0x02080100,
 | |
|                 0x40000100};
 | |
| 
 | |
|         private static int[] SP6 = {
 | |
|                 0x20000010,
 | |
|                 0x20400000,
 | |
|                 0x00004000,
 | |
|                 0x20404010,
 | |
|                 0x20400000,
 | |
|                 0x00000010,
 | |
|                 0x20404010,
 | |
|                 0x00400000,
 | |
|                 0x20004000,
 | |
|                 0x00404010,
 | |
|                 0x00400000,
 | |
|                 0x20000010,
 | |
|                 0x00400010,
 | |
|                 0x20004000,
 | |
|                 0x20000000,
 | |
|                 0x00004010,
 | |
|                 0x00000000,
 | |
|                 0x00400010,
 | |
|                 0x20004010,
 | |
|                 0x00004000,
 | |
|                 0x00404000,
 | |
|                 0x20004010,
 | |
|                 0x00000010,
 | |
|                 0x20400010,
 | |
|                 0x20400010,
 | |
|                 0x00000000,
 | |
|                 0x00404010,
 | |
|                 0x20404000,
 | |
|                 0x00004010,
 | |
|                 0x00404000,
 | |
|                 0x20404000,
 | |
|                 0x20000000,
 | |
|                 0x20004000,
 | |
|                 0x00000010,
 | |
|                 0x20400010,
 | |
|                 0x00404000,
 | |
|                 0x20404010,
 | |
|                 0x00400000,
 | |
|                 0x00004010,
 | |
|                 0x20000010,
 | |
|                 0x00400000,
 | |
|                 0x20004000,
 | |
|                 0x20000000,
 | |
|                 0x00004010,
 | |
|                 0x20000010,
 | |
|                 0x20404010,
 | |
|                 0x00404000,
 | |
|                 0x20400000,
 | |
|                 0x00404010,
 | |
|                 0x20404000,
 | |
|                 0x00000000,
 | |
|                 0x20400010,
 | |
|                 0x00000010,
 | |
|                 0x00004000,
 | |
|                 0x20400000,
 | |
|                 0x00404010,
 | |
|                 0x00004000,
 | |
|                 0x00400010,
 | |
|                 0x20004010,
 | |
|                 0x00000000,
 | |
|                 0x20404000,
 | |
|                 0x20000000,
 | |
|                 0x00400010,
 | |
|                 0x20004010};
 | |
| 
 | |
|         private static int[] SP7 = {
 | |
|                 0x00200000,
 | |
|                 0x04200002,
 | |
|                 0x04000802,
 | |
|                 0x00000000,
 | |
|                 0x00000800,
 | |
|                 0x04000802,
 | |
|                 0x00200802,
 | |
|                 0x04200800,
 | |
|                 0x04200802,
 | |
|                 0x00200000,
 | |
|                 0x00000000,
 | |
|                 0x04000002,
 | |
|                 0x00000002,
 | |
|                 0x04000000,
 | |
|                 0x04200002,
 | |
|                 0x00000802,
 | |
|                 0x04000800,
 | |
|                 0x00200802,
 | |
|                 0x00200002,
 | |
|                 0x04000800,
 | |
|                 0x04000002,
 | |
|                 0x04200000,
 | |
|                 0x04200800,
 | |
|                 0x00200002,
 | |
|                 0x04200000,
 | |
|                 0x00000800,
 | |
|                 0x00000802,
 | |
|                 0x04200802,
 | |
|                 0x00200800,
 | |
|                 0x00000002,
 | |
|                 0x04000000,
 | |
|                 0x00200800,
 | |
|                 0x04000000,
 | |
|                 0x00200800,
 | |
|                 0x00200000,
 | |
|                 0x04000802,
 | |
|                 0x04000802,
 | |
|                 0x04200002,
 | |
|                 0x04200002,
 | |
|                 0x00000002,
 | |
|                 0x00200002,
 | |
|                 0x04000000,
 | |
|                 0x04000800,
 | |
|                 0x00200000,
 | |
|                 0x04200800,
 | |
|                 0x00000802,
 | |
|                 0x00200802,
 | |
|                 0x04200800,
 | |
|                 0x00000802,
 | |
|                 0x04000002,
 | |
|                 0x04200802,
 | |
|                 0x04200000,
 | |
|                 0x00200800,
 | |
|                 0x00000000,
 | |
|                 0x00000002,
 | |
|                 0x04200802,
 | |
|                 0x00000000,
 | |
|                 0x00200802,
 | |
|                 0x04200000,
 | |
|                 0x00000800,
 | |
|                 0x04000002,
 | |
|                 0x04000800,
 | |
|                 0x00000800,
 | |
|                 0x00200002};
 | |
| 
 | |
|         private static int[] SP8 = {
 | |
|                 0x10001040,
 | |
|                 0x00001000,
 | |
|                 0x00040000,
 | |
|                 0x10041040,
 | |
|                 0x10000000,
 | |
|                 0x10001040,
 | |
|                 0x00000040,
 | |
|                 0x10000000,
 | |
|                 0x00040040,
 | |
|                 0x10040000,
 | |
|                 0x10041040,
 | |
|                 0x00041000,
 | |
|                 0x10041000,
 | |
|                 0x00041040,
 | |
|                 0x00001000,
 | |
|                 0x00000040,
 | |
|                 0x10040000,
 | |
|                 0x10000040,
 | |
|                 0x10001000,
 | |
|                 0x00001040,
 | |
|                 0x00041000,
 | |
|                 0x00040040,
 | |
|                 0x10040040,
 | |
|                 0x10041000,
 | |
|                 0x00001040,
 | |
|                 0x00000000,
 | |
|                 0x00000000,
 | |
|                 0x10040040,
 | |
|                 0x10000040,
 | |
|                 0x10001000,
 | |
|                 0x00041040,
 | |
|                 0x00040000,
 | |
|                 0x00041040,
 | |
|                 0x00040000,
 | |
|                 0x10041000,
 | |
|                 0x00001000,
 | |
|                 0x00000040,
 | |
|                 0x10040040,
 | |
|                 0x00001000,
 | |
|                 0x00041040,
 | |
|                 0x10001000,
 | |
|                 0x00000040,
 | |
|                 0x10000040,
 | |
|                 0x10040000,
 | |
|                 0x10040040,
 | |
|                 0x10000000,
 | |
|                 0x00040000,
 | |
|                 0x10001040,
 | |
|                 0x00000000,
 | |
|                 0x10041040,
 | |
|                 0x00040040,
 | |
|                 0x10000040,
 | |
|                 0x10040000,
 | |
|                 0x10001000,
 | |
|                 0x10001040,
 | |
|                 0x00000000,
 | |
|                 0x10041040,
 | |
|                 0x00041000,
 | |
|                 0x00041000,
 | |
|                 0x00001040,
 | |
|                 0x00001040,
 | |
|                 0x00040040,
 | |
|                 0x10000000,
 | |
|                 0x10041000};
 | |
| 
 | |
|         public static void squashBytesToInts(byte[] inBytes, int inOff, int[] outInts, int outOff,
 | |
|                 int intLen) {
 | |
|             for (int i = 0; i < intLen; ++i)
 | |
|                 outInts[outOff + i] = ((inBytes[inOff + i * 4] & 0xff) << 24)
 | |
|                         | ((inBytes[inOff + i * 4 + 1] & 0xff) << 16)
 | |
|                         | ((inBytes[inOff + i * 4 + 2] & 0xff) << 8)
 | |
|                         | (inBytes[inOff + i * 4 + 3] & 0xff);
 | |
|         }
 | |
| 
 | |
|         public static void spreadIntsToBytes(int[] inInts, int inOff, byte[] outBytes, int outOff,
 | |
|                 int intLen) {
 | |
|             for (int i = 0; i < intLen; ++i) {
 | |
|                 outBytes[outOff + i * 4] = (byte)(inInts[inOff + i] >>> 24);
 | |
|                 outBytes[outOff + i * 4 + 1] = (byte)(inInts[inOff + i] >>> 16);
 | |
|                 outBytes[outOff + i * 4 + 2] = (byte)(inInts[inOff + i] >>> 8);
 | |
|                 outBytes[outOff + i * 4 + 3] = (byte)inInts[inOff + i];
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class MD4 extends MessageDigest implements Cloneable {
 | |
|         private static final int BLOCK_LENGTH = 64;
 | |
| 
 | |
|         private int[] context = new int[4];
 | |
| 
 | |
|         private long count;
 | |
| 
 | |
|         private byte[] buffer = new byte[BLOCK_LENGTH];
 | |
| 
 | |
|         private int[] X = new int[16];
 | |
| 
 | |
|         public MD4() {
 | |
|             super("MD4");
 | |
|             engineReset();
 | |
|         }
 | |
| 
 | |
|         private MD4(MD4 md) {
 | |
|             this();
 | |
|             context = (int[])md.context.clone();
 | |
|             buffer = (byte[])md.buffer.clone();
 | |
|             count = md.count;
 | |
|         }
 | |
| 
 | |
|         public Object clone() {
 | |
|             return new MD4(this);
 | |
|         }
 | |
| 
 | |
|         public void engineReset() {
 | |
|             context[0] = 0x67452301;
 | |
|             context[1] = 0xEFCDAB89;
 | |
|             context[2] = 0x98BADCFE;
 | |
|             context[3] = 0x10325476;
 | |
|             count = 0L;
 | |
|             for (int i = 0; i < BLOCK_LENGTH; i++)
 | |
|                 buffer[i] = 0;
 | |
|         }
 | |
| 
 | |
|         public void engineUpdate(byte b) {
 | |
|             int i = (int)(count % BLOCK_LENGTH);
 | |
|             count++;
 | |
|             buffer[i] = b;
 | |
|             if (i == BLOCK_LENGTH - 1) transform(buffer, 0);
 | |
|         }
 | |
| 
 | |
|         public void engineUpdate(byte[] input, int offset, int len) {
 | |
|             if (offset < 0 || len < 0 || (long)offset + len > input.length)
 | |
|                 throw new ArrayIndexOutOfBoundsException();
 | |
|             int bufferNdx = (int)(count % BLOCK_LENGTH);
 | |
|             count += len;
 | |
|             int partLen = BLOCK_LENGTH - bufferNdx;
 | |
|             int i = 0;
 | |
|             if (len >= partLen) {
 | |
|                 System.arraycopy(input, offset, buffer, bufferNdx, partLen);
 | |
|                 transform(buffer, 0);
 | |
|                 for (i = partLen; i + BLOCK_LENGTH - 1 < len; i += BLOCK_LENGTH)
 | |
|                     transform(input, offset + i);
 | |
|                 bufferNdx = 0;
 | |
|             }
 | |
|             if (i < len) System.arraycopy(input, offset + i, buffer, bufferNdx, len - i);
 | |
|         }
 | |
| 
 | |
|         public byte[] engineDigest() {
 | |
|             int bufferNdx = (int)(count % BLOCK_LENGTH);
 | |
|             int padLen = (bufferNdx < 56)? (56 - bufferNdx): (120 - bufferNdx);
 | |
|             byte[] tail = new byte[padLen + 8];
 | |
|             tail[0] = (byte)0x80;
 | |
|             for (int i = 0; i < 8; i++)
 | |
|                 tail[padLen + i] = (byte)((count * 8) >>> (8 * i));
 | |
|             engineUpdate(tail, 0, tail.length);
 | |
|             byte[] result = new byte[16];
 | |
|             for (int i = 0; i < 4; i++)
 | |
|                 for (int j = 0; j < 4; j++)
 | |
|                     result[i * 4 + j] = (byte)(context[i] >>> (8 * j));
 | |
|             engineReset();
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         private void transform(byte[] block, int offset) {
 | |
|             for (int i = 0; i < 16; i++)
 | |
|                 X[i] = (block[offset++] & 0xFF) | (block[offset++] & 0xFF) << 8
 | |
|                         | (block[offset++] & 0xFF) << 16 | (block[offset++] & 0xFF) << 24;
 | |
|             int A = context[0];
 | |
|             int B = context[1];
 | |
|             int C = context[2];
 | |
|             int D = context[3];
 | |
|             A = FF(A, B, C, D, X[0], 3);
 | |
|             D = FF(D, A, B, C, X[1], 7);
 | |
|             C = FF(C, D, A, B, X[2], 11);
 | |
|             B = FF(B, C, D, A, X[3], 19);
 | |
|             A = FF(A, B, C, D, X[4], 3);
 | |
|             D = FF(D, A, B, C, X[5], 7);
 | |
|             C = FF(C, D, A, B, X[6], 11);
 | |
|             B = FF(B, C, D, A, X[7], 19);
 | |
|             A = FF(A, B, C, D, X[8], 3);
 | |
|             D = FF(D, A, B, C, X[9], 7);
 | |
|             C = FF(C, D, A, B, X[10], 11);
 | |
|             B = FF(B, C, D, A, X[11], 19);
 | |
|             A = FF(A, B, C, D, X[12], 3);
 | |
|             D = FF(D, A, B, C, X[13], 7);
 | |
|             C = FF(C, D, A, B, X[14], 11);
 | |
|             B = FF(B, C, D, A, X[15], 19);
 | |
|             A = GG(A, B, C, D, X[0], 3);
 | |
|             D = GG(D, A, B, C, X[4], 5);
 | |
|             C = GG(C, D, A, B, X[8], 9);
 | |
|             B = GG(B, C, D, A, X[12], 13);
 | |
|             A = GG(A, B, C, D, X[1], 3);
 | |
|             D = GG(D, A, B, C, X[5], 5);
 | |
|             C = GG(C, D, A, B, X[9], 9);
 | |
|             B = GG(B, C, D, A, X[13], 13);
 | |
|             A = GG(A, B, C, D, X[2], 3);
 | |
|             D = GG(D, A, B, C, X[6], 5);
 | |
|             C = GG(C, D, A, B, X[10], 9);
 | |
|             B = GG(B, C, D, A, X[14], 13);
 | |
|             A = GG(A, B, C, D, X[3], 3);
 | |
|             D = GG(D, A, B, C, X[7], 5);
 | |
|             C = GG(C, D, A, B, X[11], 9);
 | |
|             B = GG(B, C, D, A, X[15], 13);
 | |
|             A = HH(A, B, C, D, X[0], 3);
 | |
|             D = HH(D, A, B, C, X[8], 9);
 | |
|             C = HH(C, D, A, B, X[4], 11);
 | |
|             B = HH(B, C, D, A, X[12], 15);
 | |
|             A = HH(A, B, C, D, X[2], 3);
 | |
|             D = HH(D, A, B, C, X[10], 9);
 | |
|             C = HH(C, D, A, B, X[6], 11);
 | |
|             B = HH(B, C, D, A, X[14], 15);
 | |
|             A = HH(A, B, C, D, X[1], 3);
 | |
|             D = HH(D, A, B, C, X[9], 9);
 | |
|             C = HH(C, D, A, B, X[5], 11);
 | |
|             B = HH(B, C, D, A, X[13], 15);
 | |
|             A = HH(A, B, C, D, X[3], 3);
 | |
|             D = HH(D, A, B, C, X[11], 9);
 | |
|             C = HH(C, D, A, B, X[7], 11);
 | |
|             B = HH(B, C, D, A, X[15], 15);
 | |
|             context[0] += A;
 | |
|             context[1] += B;
 | |
|             context[2] += C;
 | |
|             context[3] += D;
 | |
|         }
 | |
| 
 | |
|         private int FF(int a, int b, int c, int d, int x, int s) {
 | |
|             int t = a + ((b & c) | (~b & d)) + x;
 | |
|             return t << s | t >>> (32 - s);
 | |
|         }
 | |
| 
 | |
|         private int GG(int a, int b, int c, int d, int x, int s) {
 | |
|             int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
 | |
|             return t << s | t >>> (32 - s);
 | |
|         }
 | |
| 
 | |
|         private int HH(int a, int b, int c, int d, int x, int s) {
 | |
|             int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
 | |
|             return t << s | t >>> (32 - s);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class jcrypt {
 | |
|         private jcrypt() {
 | |
|         }
 | |
| 
 | |
|         private static final int ITERATIONS = 16;
 | |
| 
 | |
|         private static final int con_salt[] = {
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x01,
 | |
|                 0x02,
 | |
|                 0x03,
 | |
|                 0x04,
 | |
|                 0x05,
 | |
|                 0x06,
 | |
|                 0x07,
 | |
|                 0x08,
 | |
|                 0x09,
 | |
|                 0x0A,
 | |
|                 0x0B,
 | |
|                 0x05,
 | |
|                 0x06,
 | |
|                 0x07,
 | |
|                 0x08,
 | |
|                 0x09,
 | |
|                 0x0A,
 | |
|                 0x0B,
 | |
|                 0x0C,
 | |
|                 0x0D,
 | |
|                 0x0E,
 | |
|                 0x0F,
 | |
|                 0x10,
 | |
|                 0x11,
 | |
|                 0x12,
 | |
|                 0x13,
 | |
|                 0x14,
 | |
|                 0x15,
 | |
|                 0x16,
 | |
|                 0x17,
 | |
|                 0x18,
 | |
|                 0x19,
 | |
|                 0x1A,
 | |
|                 0x1B,
 | |
|                 0x1C,
 | |
|                 0x1D,
 | |
|                 0x1E,
 | |
|                 0x1F,
 | |
|                 0x20,
 | |
|                 0x21,
 | |
|                 0x22,
 | |
|                 0x23,
 | |
|                 0x24,
 | |
|                 0x25,
 | |
|                 0x20,
 | |
|                 0x21,
 | |
|                 0x22,
 | |
|                 0x23,
 | |
|                 0x24,
 | |
|                 0x25,
 | |
|                 0x26,
 | |
|                 0x27,
 | |
|                 0x28,
 | |
|                 0x29,
 | |
|                 0x2A,
 | |
|                 0x2B,
 | |
|                 0x2C,
 | |
|                 0x2D,
 | |
|                 0x2E,
 | |
|                 0x2F,
 | |
|                 0x30,
 | |
|                 0x31,
 | |
|                 0x32,
 | |
|                 0x33,
 | |
|                 0x34,
 | |
|                 0x35,
 | |
|                 0x36,
 | |
|                 0x37,
 | |
|                 0x38,
 | |
|                 0x39,
 | |
|                 0x3A,
 | |
|                 0x3B,
 | |
|                 0x3C,
 | |
|                 0x3D,
 | |
|                 0x3E,
 | |
|                 0x3F,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,
 | |
|                 0x00,};
 | |
| 
 | |
|         private static final boolean shifts2[] = {
 | |
|                 false,
 | |
|                 false,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 false,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 true,
 | |
|                 false};
 | |
| 
 | |
|         private static final int skb[][] = {
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x00000010,
 | |
|                         0x20000000,
 | |
|                         0x20000010,
 | |
|                         0x00010000,
 | |
|                         0x00010010,
 | |
|                         0x20010000,
 | |
|                         0x20010010,
 | |
|                         0x00000800,
 | |
|                         0x00000810,
 | |
|                         0x20000800,
 | |
|                         0x20000810,
 | |
|                         0x00010800,
 | |
|                         0x00010810,
 | |
|                         0x20010800,
 | |
|                         0x20010810,
 | |
|                         0x00000020,
 | |
|                         0x00000030,
 | |
|                         0x20000020,
 | |
|                         0x20000030,
 | |
|                         0x00010020,
 | |
|                         0x00010030,
 | |
|                         0x20010020,
 | |
|                         0x20010030,
 | |
|                         0x00000820,
 | |
|                         0x00000830,
 | |
|                         0x20000820,
 | |
|                         0x20000830,
 | |
|                         0x00010820,
 | |
|                         0x00010830,
 | |
|                         0x20010820,
 | |
|                         0x20010830,
 | |
|                         0x00080000,
 | |
|                         0x00080010,
 | |
|                         0x20080000,
 | |
|                         0x20080010,
 | |
|                         0x00090000,
 | |
|                         0x00090010,
 | |
|                         0x20090000,
 | |
|                         0x20090010,
 | |
|                         0x00080800,
 | |
|                         0x00080810,
 | |
|                         0x20080800,
 | |
|                         0x20080810,
 | |
|                         0x00090800,
 | |
|                         0x00090810,
 | |
|                         0x20090800,
 | |
|                         0x20090810,
 | |
|                         0x00080020,
 | |
|                         0x00080030,
 | |
|                         0x20080020,
 | |
|                         0x20080030,
 | |
|                         0x00090020,
 | |
|                         0x00090030,
 | |
|                         0x20090020,
 | |
|                         0x20090030,
 | |
|                         0x00080820,
 | |
|                         0x00080830,
 | |
|                         0x20080820,
 | |
|                         0x20080830,
 | |
|                         0x00090820,
 | |
|                         0x00090830,
 | |
|                         0x20090820,
 | |
|                         0x20090830,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x02000000,
 | |
|                         0x00002000,
 | |
|                         0x02002000,
 | |
|                         0x00200000,
 | |
|                         0x02200000,
 | |
|                         0x00202000,
 | |
|                         0x02202000,
 | |
|                         0x00000004,
 | |
|                         0x02000004,
 | |
|                         0x00002004,
 | |
|                         0x02002004,
 | |
|                         0x00200004,
 | |
|                         0x02200004,
 | |
|                         0x00202004,
 | |
|                         0x02202004,
 | |
|                         0x00000400,
 | |
|                         0x02000400,
 | |
|                         0x00002400,
 | |
|                         0x02002400,
 | |
|                         0x00200400,
 | |
|                         0x02200400,
 | |
|                         0x00202400,
 | |
|                         0x02202400,
 | |
|                         0x00000404,
 | |
|                         0x02000404,
 | |
|                         0x00002404,
 | |
|                         0x02002404,
 | |
|                         0x00200404,
 | |
|                         0x02200404,
 | |
|                         0x00202404,
 | |
|                         0x02202404,
 | |
|                         0x10000000,
 | |
|                         0x12000000,
 | |
|                         0x10002000,
 | |
|                         0x12002000,
 | |
|                         0x10200000,
 | |
|                         0x12200000,
 | |
|                         0x10202000,
 | |
|                         0x12202000,
 | |
|                         0x10000004,
 | |
|                         0x12000004,
 | |
|                         0x10002004,
 | |
|                         0x12002004,
 | |
|                         0x10200004,
 | |
|                         0x12200004,
 | |
|                         0x10202004,
 | |
|                         0x12202004,
 | |
|                         0x10000400,
 | |
|                         0x12000400,
 | |
|                         0x10002400,
 | |
|                         0x12002400,
 | |
|                         0x10200400,
 | |
|                         0x12200400,
 | |
|                         0x10202400,
 | |
|                         0x12202400,
 | |
|                         0x10000404,
 | |
|                         0x12000404,
 | |
|                         0x10002404,
 | |
|                         0x12002404,
 | |
|                         0x10200404,
 | |
|                         0x12200404,
 | |
|                         0x10202404,
 | |
|                         0x12202404,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x00000001,
 | |
|                         0x00040000,
 | |
|                         0x00040001,
 | |
|                         0x01000000,
 | |
|                         0x01000001,
 | |
|                         0x01040000,
 | |
|                         0x01040001,
 | |
|                         0x00000002,
 | |
|                         0x00000003,
 | |
|                         0x00040002,
 | |
|                         0x00040003,
 | |
|                         0x01000002,
 | |
|                         0x01000003,
 | |
|                         0x01040002,
 | |
|                         0x01040003,
 | |
|                         0x00000200,
 | |
|                         0x00000201,
 | |
|                         0x00040200,
 | |
|                         0x00040201,
 | |
|                         0x01000200,
 | |
|                         0x01000201,
 | |
|                         0x01040200,
 | |
|                         0x01040201,
 | |
|                         0x00000202,
 | |
|                         0x00000203,
 | |
|                         0x00040202,
 | |
|                         0x00040203,
 | |
|                         0x01000202,
 | |
|                         0x01000203,
 | |
|                         0x01040202,
 | |
|                         0x01040203,
 | |
|                         0x08000000,
 | |
|                         0x08000001,
 | |
|                         0x08040000,
 | |
|                         0x08040001,
 | |
|                         0x09000000,
 | |
|                         0x09000001,
 | |
|                         0x09040000,
 | |
|                         0x09040001,
 | |
|                         0x08000002,
 | |
|                         0x08000003,
 | |
|                         0x08040002,
 | |
|                         0x08040003,
 | |
|                         0x09000002,
 | |
|                         0x09000003,
 | |
|                         0x09040002,
 | |
|                         0x09040003,
 | |
|                         0x08000200,
 | |
|                         0x08000201,
 | |
|                         0x08040200,
 | |
|                         0x08040201,
 | |
|                         0x09000200,
 | |
|                         0x09000201,
 | |
|                         0x09040200,
 | |
|                         0x09040201,
 | |
|                         0x08000202,
 | |
|                         0x08000203,
 | |
|                         0x08040202,
 | |
|                         0x08040203,
 | |
|                         0x09000202,
 | |
|                         0x09000203,
 | |
|                         0x09040202,
 | |
|                         0x09040203,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x00100000,
 | |
|                         0x00000100,
 | |
|                         0x00100100,
 | |
|                         0x00000008,
 | |
|                         0x00100008,
 | |
|                         0x00000108,
 | |
|                         0x00100108,
 | |
|                         0x00001000,
 | |
|                         0x00101000,
 | |
|                         0x00001100,
 | |
|                         0x00101100,
 | |
|                         0x00001008,
 | |
|                         0x00101008,
 | |
|                         0x00001108,
 | |
|                         0x00101108,
 | |
|                         0x04000000,
 | |
|                         0x04100000,
 | |
|                         0x04000100,
 | |
|                         0x04100100,
 | |
|                         0x04000008,
 | |
|                         0x04100008,
 | |
|                         0x04000108,
 | |
|                         0x04100108,
 | |
|                         0x04001000,
 | |
|                         0x04101000,
 | |
|                         0x04001100,
 | |
|                         0x04101100,
 | |
|                         0x04001008,
 | |
|                         0x04101008,
 | |
|                         0x04001108,
 | |
|                         0x04101108,
 | |
|                         0x00020000,
 | |
|                         0x00120000,
 | |
|                         0x00020100,
 | |
|                         0x00120100,
 | |
|                         0x00020008,
 | |
|                         0x00120008,
 | |
|                         0x00020108,
 | |
|                         0x00120108,
 | |
|                         0x00021000,
 | |
|                         0x00121000,
 | |
|                         0x00021100,
 | |
|                         0x00121100,
 | |
|                         0x00021008,
 | |
|                         0x00121008,
 | |
|                         0x00021108,
 | |
|                         0x00121108,
 | |
|                         0x04020000,
 | |
|                         0x04120000,
 | |
|                         0x04020100,
 | |
|                         0x04120100,
 | |
|                         0x04020008,
 | |
|                         0x04120008,
 | |
|                         0x04020108,
 | |
|                         0x04120108,
 | |
|                         0x04021000,
 | |
|                         0x04121000,
 | |
|                         0x04021100,
 | |
|                         0x04121100,
 | |
|                         0x04021008,
 | |
|                         0x04121008,
 | |
|                         0x04021108,
 | |
|                         0x04121108,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x10000000,
 | |
|                         0x00010000,
 | |
|                         0x10010000,
 | |
|                         0x00000004,
 | |
|                         0x10000004,
 | |
|                         0x00010004,
 | |
|                         0x10010004,
 | |
|                         0x20000000,
 | |
|                         0x30000000,
 | |
|                         0x20010000,
 | |
|                         0x30010000,
 | |
|                         0x20000004,
 | |
|                         0x30000004,
 | |
|                         0x20010004,
 | |
|                         0x30010004,
 | |
|                         0x00100000,
 | |
|                         0x10100000,
 | |
|                         0x00110000,
 | |
|                         0x10110000,
 | |
|                         0x00100004,
 | |
|                         0x10100004,
 | |
|                         0x00110004,
 | |
|                         0x10110004,
 | |
|                         0x20100000,
 | |
|                         0x30100000,
 | |
|                         0x20110000,
 | |
|                         0x30110000,
 | |
|                         0x20100004,
 | |
|                         0x30100004,
 | |
|                         0x20110004,
 | |
|                         0x30110004,
 | |
|                         0x00001000,
 | |
|                         0x10001000,
 | |
|                         0x00011000,
 | |
|                         0x10011000,
 | |
|                         0x00001004,
 | |
|                         0x10001004,
 | |
|                         0x00011004,
 | |
|                         0x10011004,
 | |
|                         0x20001000,
 | |
|                         0x30001000,
 | |
|                         0x20011000,
 | |
|                         0x30011000,
 | |
|                         0x20001004,
 | |
|                         0x30001004,
 | |
|                         0x20011004,
 | |
|                         0x30011004,
 | |
|                         0x00101000,
 | |
|                         0x10101000,
 | |
|                         0x00111000,
 | |
|                         0x10111000,
 | |
|                         0x00101004,
 | |
|                         0x10101004,
 | |
|                         0x00111004,
 | |
|                         0x10111004,
 | |
|                         0x20101000,
 | |
|                         0x30101000,
 | |
|                         0x20111000,
 | |
|                         0x30111000,
 | |
|                         0x20101004,
 | |
|                         0x30101004,
 | |
|                         0x20111004,
 | |
|                         0x30111004,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x08000000,
 | |
|                         0x00000008,
 | |
|                         0x08000008,
 | |
|                         0x00000400,
 | |
|                         0x08000400,
 | |
|                         0x00000408,
 | |
|                         0x08000408,
 | |
|                         0x00020000,
 | |
|                         0x08020000,
 | |
|                         0x00020008,
 | |
|                         0x08020008,
 | |
|                         0x00020400,
 | |
|                         0x08020400,
 | |
|                         0x00020408,
 | |
|                         0x08020408,
 | |
|                         0x00000001,
 | |
|                         0x08000001,
 | |
|                         0x00000009,
 | |
|                         0x08000009,
 | |
|                         0x00000401,
 | |
|                         0x08000401,
 | |
|                         0x00000409,
 | |
|                         0x08000409,
 | |
|                         0x00020001,
 | |
|                         0x08020001,
 | |
|                         0x00020009,
 | |
|                         0x08020009,
 | |
|                         0x00020401,
 | |
|                         0x08020401,
 | |
|                         0x00020409,
 | |
|                         0x08020409,
 | |
|                         0x02000000,
 | |
|                         0x0A000000,
 | |
|                         0x02000008,
 | |
|                         0x0A000008,
 | |
|                         0x02000400,
 | |
|                         0x0A000400,
 | |
|                         0x02000408,
 | |
|                         0x0A000408,
 | |
|                         0x02020000,
 | |
|                         0x0A020000,
 | |
|                         0x02020008,
 | |
|                         0x0A020008,
 | |
|                         0x02020400,
 | |
|                         0x0A020400,
 | |
|                         0x02020408,
 | |
|                         0x0A020408,
 | |
|                         0x02000001,
 | |
|                         0x0A000001,
 | |
|                         0x02000009,
 | |
|                         0x0A000009,
 | |
|                         0x02000401,
 | |
|                         0x0A000401,
 | |
|                         0x02000409,
 | |
|                         0x0A000409,
 | |
|                         0x02020001,
 | |
|                         0x0A020001,
 | |
|                         0x02020009,
 | |
|                         0x0A020009,
 | |
|                         0x02020401,
 | |
|                         0x0A020401,
 | |
|                         0x02020409,
 | |
|                         0x0A020409,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x00000100,
 | |
|                         0x00080000,
 | |
|                         0x00080100,
 | |
|                         0x01000000,
 | |
|                         0x01000100,
 | |
|                         0x01080000,
 | |
|                         0x01080100,
 | |
|                         0x00000010,
 | |
|                         0x00000110,
 | |
|                         0x00080010,
 | |
|                         0x00080110,
 | |
|                         0x01000010,
 | |
|                         0x01000110,
 | |
|                         0x01080010,
 | |
|                         0x01080110,
 | |
|                         0x00200000,
 | |
|                         0x00200100,
 | |
|                         0x00280000,
 | |
|                         0x00280100,
 | |
|                         0x01200000,
 | |
|                         0x01200100,
 | |
|                         0x01280000,
 | |
|                         0x01280100,
 | |
|                         0x00200010,
 | |
|                         0x00200110,
 | |
|                         0x00280010,
 | |
|                         0x00280110,
 | |
|                         0x01200010,
 | |
|                         0x01200110,
 | |
|                         0x01280010,
 | |
|                         0x01280110,
 | |
|                         0x00000200,
 | |
|                         0x00000300,
 | |
|                         0x00080200,
 | |
|                         0x00080300,
 | |
|                         0x01000200,
 | |
|                         0x01000300,
 | |
|                         0x01080200,
 | |
|                         0x01080300,
 | |
|                         0x00000210,
 | |
|                         0x00000310,
 | |
|                         0x00080210,
 | |
|                         0x00080310,
 | |
|                         0x01000210,
 | |
|                         0x01000310,
 | |
|                         0x01080210,
 | |
|                         0x01080310,
 | |
|                         0x00200200,
 | |
|                         0x00200300,
 | |
|                         0x00280200,
 | |
|                         0x00280300,
 | |
|                         0x01200200,
 | |
|                         0x01200300,
 | |
|                         0x01280200,
 | |
|                         0x01280300,
 | |
|                         0x00200210,
 | |
|                         0x00200310,
 | |
|                         0x00280210,
 | |
|                         0x00280310,
 | |
|                         0x01200210,
 | |
|                         0x01200310,
 | |
|                         0x01280210,
 | |
|                         0x01280310,},
 | |
|                 {
 | |
|                         0x00000000,
 | |
|                         0x04000000,
 | |
|                         0x00040000,
 | |
|                         0x04040000,
 | |
|                         0x00000002,
 | |
|                         0x04000002,
 | |
|                         0x00040002,
 | |
|                         0x04040002,
 | |
|                         0x00002000,
 | |
|                         0x04002000,
 | |
|                         0x00042000,
 | |
|                         0x04042000,
 | |
|                         0x00002002,
 | |
|                         0x04002002,
 | |
|                         0x00042002,
 | |
|                         0x04042002,
 | |
|                         0x00000020,
 | |
|                         0x04000020,
 | |
|                         0x00040020,
 | |
|                         0x04040020,
 | |
|                         0x00000022,
 | |
|                         0x04000022,
 | |
|                         0x00040022,
 | |
|                         0x04040022,
 | |
|                         0x00002020,
 | |
|                         0x04002020,
 | |
|                         0x00042020,
 | |
|                         0x04042020,
 | |
|                         0x00002022,
 | |
|                         0x04002022,
 | |
|                         0x00042022,
 | |
|                         0x04042022,
 | |
|                         0x00000800,
 | |
|                         0x04000800,
 | |
|                         0x00040800,
 | |
|                         0x04040800,
 | |
|                         0x00000802,
 | |
|                         0x04000802,
 | |
|                         0x00040802,
 | |
|                         0x04040802,
 | |
|                         0x00002800,
 | |
|                         0x04002800,
 | |
|                         0x00042800,
 | |
|                         0x04042800,
 | |
|                         0x00002802,
 | |
|                         0x04002802,
 | |
|                         0x00042802,
 | |
|                         0x04042802,
 | |
|                         0x00000820,
 | |
|                         0x04000820,
 | |
|                         0x00040820,
 | |
|                         0x04040820,
 | |
|                         0x00000822,
 | |
|                         0x04000822,
 | |
|                         0x00040822,
 | |
|                         0x04040822,
 | |
|                         0x00002820,
 | |
|                         0x04002820,
 | |
|                         0x00042820,
 | |
|                         0x04042820,
 | |
|                         0x00002822,
 | |
|                         0x04002822,
 | |
|                         0x00042822,
 | |
|                         0x04042822,},};
 | |
| 
 | |
|         private static final int SPtrans[][] = {
 | |
|                 {
 | |
|                         0x00820200,
 | |
|                         0x00020000,
 | |
|                         0x80800000,
 | |
|                         0x80820200,
 | |
|                         0x00800000,
 | |
|                         0x80020200,
 | |
|                         0x80020000,
 | |
|                         0x80800000,
 | |
|                         0x80020200,
 | |
|                         0x00820200,
 | |
|                         0x00820000,
 | |
|                         0x80000200,
 | |
|                         0x80800200,
 | |
|                         0x00800000,
 | |
|                         0x00000000,
 | |
|                         0x80020000,
 | |
|                         0x00020000,
 | |
|                         0x80000000,
 | |
|                         0x00800200,
 | |
|                         0x00020200,
 | |
|                         0x80820200,
 | |
|                         0x00820000,
 | |
|                         0x80000200,
 | |
|                         0x00800200,
 | |
|                         0x80000000,
 | |
|                         0x00000200,
 | |
|                         0x00020200,
 | |
|                         0x80820000,
 | |
|                         0x00000200,
 | |
|                         0x80800200,
 | |
|                         0x80820000,
 | |
|                         0x00000000,
 | |
|                         0x00000000,
 | |
|                         0x80820200,
 | |
|                         0x00800200,
 | |
|                         0x80020000,
 | |
|                         0x00820200,
 | |
|                         0x00020000,
 | |
|                         0x80000200,
 | |
|                         0x00800200,
 | |
|                         0x80820000,
 | |
|                         0x00000200,
 | |
|                         0x00020200,
 | |
|                         0x80800000,
 | |
|                         0x80020200,
 | |
|                         0x80000000,
 | |
|                         0x80800000,
 | |
|                         0x00820000,
 | |
|                         0x80820200,
 | |
|                         0x00020200,
 | |
|                         0x00820000,
 | |
|                         0x80800200,
 | |
|                         0x00800000,
 | |
|                         0x80000200,
 | |
|                         0x80020000,
 | |
|                         0x00000000,
 | |
|                         0x00020000,
 | |
|                         0x00800000,
 | |
|                         0x80800200,
 | |
|                         0x00820200,
 | |
|                         0x80000000,
 | |
|                         0x80820000,
 | |
|                         0x00000200,
 | |
|                         0x80020200,},
 | |
|                 {
 | |
|                         0x10042004,
 | |
|                         0x00000000,
 | |
|                         0x00042000,
 | |
|                         0x10040000,
 | |
|                         0x10000004,
 | |
|                         0x00002004,
 | |
|                         0x10002000,
 | |
|                         0x00042000,
 | |
|                         0x00002000,
 | |
|                         0x10040004,
 | |
|                         0x00000004,
 | |
|                         0x10002000,
 | |
|                         0x00040004,
 | |
|                         0x10042000,
 | |
|                         0x10040000,
 | |
|                         0x00000004,
 | |
|                         0x00040000,
 | |
|                         0x10002004,
 | |
|                         0x10040004,
 | |
|                         0x00002000,
 | |
|                         0x00042004,
 | |
|                         0x10000000,
 | |
|                         0x00000000,
 | |
|                         0x00040004,
 | |
|                         0x10002004,
 | |
|                         0x00042004,
 | |
|                         0x10042000,
 | |
|                         0x10000004,
 | |
|                         0x10000000,
 | |
|                         0x00040000,
 | |
|                         0x00002004,
 | |
|                         0x10042004,
 | |
|                         0x00040004,
 | |
|                         0x10042000,
 | |
|                         0x10002000,
 | |
|                         0x00042004,
 | |
|                         0x10042004,
 | |
|                         0x00040004,
 | |
|                         0x10000004,
 | |
|                         0x00000000,
 | |
|                         0x10000000,
 | |
|                         0x00002004,
 | |
|                         0x00040000,
 | |
|                         0x10040004,
 | |
|                         0x00002000,
 | |
|                         0x10000000,
 | |
|                         0x00042004,
 | |
|                         0x10002004,
 | |
|                         0x10042000,
 | |
|                         0x00002000,
 | |
|                         0x00000000,
 | |
|                         0x10000004,
 | |
|                         0x00000004,
 | |
|                         0x10042004,
 | |
|                         0x00042000,
 | |
|                         0x10040000,
 | |
|                         0x10040004,
 | |
|                         0x00040000,
 | |
|                         0x00002004,
 | |
|                         0x10002000,
 | |
|                         0x10002004,
 | |
|                         0x00000004,
 | |
|                         0x10040000,
 | |
|                         0x00042000,},
 | |
|                 {
 | |
|                         0x41000000,
 | |
|                         0x01010040,
 | |
|                         0x00000040,
 | |
|                         0x41000040,
 | |
|                         0x40010000,
 | |
|                         0x01000000,
 | |
|                         0x41000040,
 | |
|                         0x00010040,
 | |
|                         0x01000040,
 | |
|                         0x00010000,
 | |
|                         0x01010000,
 | |
|                         0x40000000,
 | |
|                         0x41010040,
 | |
|                         0x40000040,
 | |
|                         0x40000000,
 | |
|                         0x41010000,
 | |
|                         0x00000000,
 | |
|                         0x40010000,
 | |
|                         0x01010040,
 | |
|                         0x00000040,
 | |
|                         0x40000040,
 | |
|                         0x41010040,
 | |
|                         0x00010000,
 | |
|                         0x41000000,
 | |
|                         0x41010000,
 | |
|                         0x01000040,
 | |
|                         0x40010040,
 | |
|                         0x01010000,
 | |
|                         0x00010040,
 | |
|                         0x00000000,
 | |
|                         0x01000000,
 | |
|                         0x40010040,
 | |
|                         0x01010040,
 | |
|                         0x00000040,
 | |
|                         0x40000000,
 | |
|                         0x00010000,
 | |
|                         0x40000040,
 | |
|                         0x40010000,
 | |
|                         0x01010000,
 | |
|                         0x41000040,
 | |
|                         0x00000000,
 | |
|                         0x01010040,
 | |
|                         0x00010040,
 | |
|                         0x41010000,
 | |
|                         0x40010000,
 | |
|                         0x01000000,
 | |
|                         0x41010040,
 | |
|                         0x40000000,
 | |
|                         0x40010040,
 | |
|                         0x41000000,
 | |
|                         0x01000000,
 | |
|                         0x41010040,
 | |
|                         0x00010000,
 | |
|                         0x01000040,
 | |
|                         0x41000040,
 | |
|                         0x00010040,
 | |
|                         0x01000040,
 | |
|                         0x00000000,
 | |
|                         0x41010000,
 | |
|                         0x40000040,
 | |
|                         0x41000000,
 | |
|                         0x40010040,
 | |
|                         0x00000040,
 | |
|                         0x01010000,},
 | |
|                 {
 | |
|                         0x00100402,
 | |
|                         0x04000400,
 | |
|                         0x00000002,
 | |
|                         0x04100402,
 | |
|                         0x00000000,
 | |
|                         0x04100000,
 | |
|                         0x04000402,
 | |
|                         0x00100002,
 | |
|                         0x04100400,
 | |
|                         0x04000002,
 | |
|                         0x04000000,
 | |
|                         0x00000402,
 | |
|                         0x04000002,
 | |
|                         0x00100402,
 | |
|                         0x00100000,
 | |
|                         0x04000000,
 | |
|                         0x04100002,
 | |
|                         0x00100400,
 | |
|                         0x00000400,
 | |
|                         0x00000002,
 | |
|                         0x00100400,
 | |
|                         0x04000402,
 | |
|                         0x04100000,
 | |
|                         0x00000400,
 | |
|                         0x00000402,
 | |
|                         0x00000000,
 | |
|                         0x00100002,
 | |
|                         0x04100400,
 | |
|                         0x04000400,
 | |
|                         0x04100002,
 | |
|                         0x04100402,
 | |
|                         0x00100000,
 | |
|                         0x04100002,
 | |
|                         0x00000402,
 | |
|                         0x00100000,
 | |
|                         0x04000002,
 | |
|                         0x00100400,
 | |
|                         0x04000400,
 | |
|                         0x00000002,
 | |
|                         0x04100000,
 | |
|                         0x04000402,
 | |
|                         0x00000000,
 | |
|                         0x00000400,
 | |
|                         0x00100002,
 | |
|                         0x00000000,
 | |
|                         0x04100002,
 | |
|                         0x04100400,
 | |
|                         0x00000400,
 | |
|                         0x04000000,
 | |
|                         0x04100402,
 | |
|                         0x00100402,
 | |
|                         0x00100000,
 | |
|                         0x04100402,
 | |
|                         0x00000002,
 | |
|                         0x04000400,
 | |
|                         0x00100402,
 | |
|                         0x00100002,
 | |
|                         0x00100400,
 | |
|                         0x04100000,
 | |
|                         0x04000402,
 | |
|                         0x00000402,
 | |
|                         0x04000000,
 | |
|                         0x04000002,
 | |
|                         0x04100400,},
 | |
|                 {
 | |
|                         0x02000000,
 | |
|                         0x00004000,
 | |
|                         0x00000100,
 | |
|                         0x02004108,
 | |
|                         0x02004008,
 | |
|                         0x02000100,
 | |
|                         0x00004108,
 | |
|                         0x02004000,
 | |
|                         0x00004000,
 | |
|                         0x00000008,
 | |
|                         0x02000008,
 | |
|                         0x00004100,
 | |
|                         0x02000108,
 | |
|                         0x02004008,
 | |
|                         0x02004100,
 | |
|                         0x00000000,
 | |
|                         0x00004100,
 | |
|                         0x02000000,
 | |
|                         0x00004008,
 | |
|                         0x00000108,
 | |
|                         0x02000100,
 | |
|                         0x00004108,
 | |
|                         0x00000000,
 | |
|                         0x02000008,
 | |
|                         0x00000008,
 | |
|                         0x02000108,
 | |
|                         0x02004108,
 | |
|                         0x00004008,
 | |
|                         0x02004000,
 | |
|                         0x00000100,
 | |
|                         0x00000108,
 | |
|                         0x02004100,
 | |
|                         0x02004100,
 | |
|                         0x02000108,
 | |
|                         0x00004008,
 | |
|                         0x02004000,
 | |
|                         0x00004000,
 | |
|                         0x00000008,
 | |
|                         0x02000008,
 | |
|                         0x02000100,
 | |
|                         0x02000000,
 | |
|                         0x00004100,
 | |
|                         0x02004108,
 | |
|                         0x00000000,
 | |
|                         0x00004108,
 | |
|                         0x02000000,
 | |
|                         0x00000100,
 | |
|                         0x00004008,
 | |
|                         0x02000108,
 | |
|                         0x00000100,
 | |
|                         0x00000000,
 | |
|                         0x02004108,
 | |
|                         0x02004008,
 | |
|                         0x02004100,
 | |
|                         0x00000108,
 | |
|                         0x00004000,
 | |
|                         0x00004100,
 | |
|                         0x02004008,
 | |
|                         0x02000100,
 | |
|                         0x00000108,
 | |
|                         0x00000008,
 | |
|                         0x00004108,
 | |
|                         0x02004000,
 | |
|                         0x02000008,},
 | |
|                 {
 | |
|                         0x20000010,
 | |
|                         0x00080010,
 | |
|                         0x00000000,
 | |
|                         0x20080800,
 | |
|                         0x00080010,
 | |
|                         0x00000800,
 | |
|                         0x20000810,
 | |
|                         0x00080000,
 | |
|                         0x00000810,
 | |
|                         0x20080810,
 | |
|                         0x00080800,
 | |
|                         0x20000000,
 | |
|                         0x20000800,
 | |
|                         0x20000010,
 | |
|                         0x20080000,
 | |
|                         0x00080810,
 | |
|                         0x00080000,
 | |
|                         0x20000810,
 | |
|                         0x20080010,
 | |
|                         0x00000000,
 | |
|                         0x00000800,
 | |
|                         0x00000010,
 | |
|                         0x20080800,
 | |
|                         0x20080010,
 | |
|                         0x20080810,
 | |
|                         0x20080000,
 | |
|                         0x20000000,
 | |
|                         0x00000810,
 | |
|                         0x00000010,
 | |
|                         0x00080800,
 | |
|                         0x00080810,
 | |
|                         0x20000800,
 | |
|                         0x00000810,
 | |
|                         0x20000000,
 | |
|                         0x20000800,
 | |
|                         0x00080810,
 | |
|                         0x20080800,
 | |
|                         0x00080010,
 | |
|                         0x00000000,
 | |
|                         0x20000800,
 | |
|                         0x20000000,
 | |
|                         0x00000800,
 | |
|                         0x20080010,
 | |
|                         0x00080000,
 | |
|                         0x00080010,
 | |
|                         0x20080810,
 | |
|                         0x00080800,
 | |
|                         0x00000010,
 | |
|                         0x20080810,
 | |
|                         0x00080800,
 | |
|                         0x00080000,
 | |
|                         0x20000810,
 | |
|                         0x20000010,
 | |
|                         0x20080000,
 | |
|                         0x00080810,
 | |
|                         0x00000000,
 | |
|                         0x00000800,
 | |
|                         0x20000010,
 | |
|                         0x20000810,
 | |
|                         0x20080800,
 | |
|                         0x20080000,
 | |
|                         0x00000810,
 | |
|                         0x00000010,
 | |
|                         0x20080010,},
 | |
|                 {
 | |
|                         0x00001000,
 | |
|                         0x00000080,
 | |
|                         0x00400080,
 | |
|                         0x00400001,
 | |
|                         0x00401081,
 | |
|                         0x00001001,
 | |
|                         0x00001080,
 | |
|                         0x00000000,
 | |
|                         0x00400000,
 | |
|                         0x00400081,
 | |
|                         0x00000081,
 | |
|                         0x00401000,
 | |
|                         0x00000001,
 | |
|                         0x00401080,
 | |
|                         0x00401000,
 | |
|                         0x00000081,
 | |
|                         0x00400081,
 | |
|                         0x00001000,
 | |
|                         0x00001001,
 | |
|                         0x00401081,
 | |
|                         0x00000000,
 | |
|                         0x00400080,
 | |
|                         0x00400001,
 | |
|                         0x00001080,
 | |
|                         0x00401001,
 | |
|                         0x00001081,
 | |
|                         0x00401080,
 | |
|                         0x00000001,
 | |
|                         0x00001081,
 | |
|                         0x00401001,
 | |
|                         0x00000080,
 | |
|                         0x00400000,
 | |
|                         0x00001081,
 | |
|                         0x00401000,
 | |
|                         0x00401001,
 | |
|                         0x00000081,
 | |
|                         0x00001000,
 | |
|                         0x00000080,
 | |
|                         0x00400000,
 | |
|                         0x00401001,
 | |
|                         0x00400081,
 | |
|                         0x00001081,
 | |
|                         0x00001080,
 | |
|                         0x00000000,
 | |
|                         0x00000080,
 | |
|                         0x00400001,
 | |
|                         0x00000001,
 | |
|                         0x00400080,
 | |
|                         0x00000000,
 | |
|                         0x00400081,
 | |
|                         0x00400080,
 | |
|                         0x00001080,
 | |
|                         0x00000081,
 | |
|                         0x00001000,
 | |
|                         0x00401081,
 | |
|                         0x00400000,
 | |
|                         0x00401080,
 | |
|                         0x00000001,
 | |
|                         0x00001001,
 | |
|                         0x00401081,
 | |
|                         0x00400001,
 | |
|                         0x00401080,
 | |
|                         0x00401000,
 | |
|                         0x00001001,},
 | |
|                 {
 | |
|                         0x08200020,
 | |
|                         0x08208000,
 | |
|                         0x00008020,
 | |
|                         0x00000000,
 | |
|                         0x08008000,
 | |
|                         0x00200020,
 | |
|                         0x08200000,
 | |
|                         0x08208020,
 | |
|                         0x00000020,
 | |
|                         0x08000000,
 | |
|                         0x00208000,
 | |
|                         0x00008020,
 | |
|                         0x00208020,
 | |
|                         0x08008020,
 | |
|                         0x08000020,
 | |
|                         0x08200000,
 | |
|                         0x00008000,
 | |
|                         0x00208020,
 | |
|                         0x00200020,
 | |
|                         0x08008000,
 | |
|                         0x08208020,
 | |
|                         0x08000020,
 | |
|                         0x00000000,
 | |
|                         0x00208000,
 | |
|                         0x08000000,
 | |
|                         0x00200000,
 | |
|                         0x08008020,
 | |
|                         0x08200020,
 | |
|                         0x00200000,
 | |
|                         0x00008000,
 | |
|                         0x08208000,
 | |
|                         0x00000020,
 | |
|                         0x00200000,
 | |
|                         0x00008000,
 | |
|                         0x08000020,
 | |
|                         0x08208020,
 | |
|                         0x00008020,
 | |
|                         0x08000000,
 | |
|                         0x00000000,
 | |
|                         0x00208000,
 | |
|                         0x08200020,
 | |
|                         0x08008020,
 | |
|                         0x08008000,
 | |
|                         0x00200020,
 | |
|                         0x08208000,
 | |
|                         0x00000020,
 | |
|                         0x00200020,
 | |
|                         0x08008000,
 | |
|                         0x08208020,
 | |
|                         0x00200000,
 | |
|                         0x08200000,
 | |
|                         0x08000020,
 | |
|                         0x00208000,
 | |
|                         0x00008020,
 | |
|                         0x08008020,
 | |
|                         0x08200000,
 | |
|                         0x00000020,
 | |
|                         0x08208000,
 | |
|                         0x00208020,
 | |
|                         0x00000000,
 | |
|                         0x08000000,
 | |
|                         0x08200020,
 | |
|                         0x00008000,
 | |
|                         0x00208020}};
 | |
| 
 | |
|         private static final int cov_2char[] = {
 | |
|                 0x2E,
 | |
|                 0x2F,
 | |
|                 0x30,
 | |
|                 0x31,
 | |
|                 0x32,
 | |
|                 0x33,
 | |
|                 0x34,
 | |
|                 0x35,
 | |
|                 0x36,
 | |
|                 0x37,
 | |
|                 0x38,
 | |
|                 0x39,
 | |
|                 0x41,
 | |
|                 0x42,
 | |
|                 0x43,
 | |
|                 0x44,
 | |
|                 0x45,
 | |
|                 0x46,
 | |
|                 0x47,
 | |
|                 0x48,
 | |
|                 0x49,
 | |
|                 0x4A,
 | |
|                 0x4B,
 | |
|                 0x4C,
 | |
|                 0x4D,
 | |
|                 0x4E,
 | |
|                 0x4F,
 | |
|                 0x50,
 | |
|                 0x51,
 | |
|                 0x52,
 | |
|                 0x53,
 | |
|                 0x54,
 | |
|                 0x55,
 | |
|                 0x56,
 | |
|                 0x57,
 | |
|                 0x58,
 | |
|                 0x59,
 | |
|                 0x5A,
 | |
|                 0x61,
 | |
|                 0x62,
 | |
|                 0x63,
 | |
|                 0x64,
 | |
|                 0x65,
 | |
|                 0x66,
 | |
|                 0x67,
 | |
|                 0x68,
 | |
|                 0x69,
 | |
|                 0x6A,
 | |
|                 0x6B,
 | |
|                 0x6C,
 | |
|                 0x6D,
 | |
|                 0x6E,
 | |
|                 0x6F,
 | |
|                 0x70,
 | |
|                 0x71,
 | |
|                 0x72,
 | |
|                 0x73,
 | |
|                 0x74,
 | |
|                 0x75,
 | |
|                 0x76,
 | |
|                 0x77,
 | |
|                 0x78,
 | |
|                 0x79,
 | |
|                 0x7A};
 | |
| 
 | |
|         private static final int byteToUnsigned(byte b) {
 | |
|             int value = (int)b;
 | |
| 
 | |
|             return (value >= 0? value: value + 256);
 | |
|         }
 | |
| 
 | |
|         private static int fourBytesToInt(byte b[], int offset) {
 | |
|             int value;
 | |
| 
 | |
|             value = byteToUnsigned(b[offset++]);
 | |
|             value |= (byteToUnsigned(b[offset++]) << 8);
 | |
|             value |= (byteToUnsigned(b[offset++]) << 16);
 | |
|             value |= (byteToUnsigned(b[offset++]) << 24);
 | |
| 
 | |
|             return (value);
 | |
|         }
 | |
| 
 | |
|         private static final void intToFourBytes(int iValue, byte b[], int offset) {
 | |
|             b[offset++] = (byte)((iValue) & 0xff);
 | |
|             b[offset++] = (byte)((iValue >>> 8) & 0xff);
 | |
|             b[offset++] = (byte)((iValue >>> 16) & 0xff);
 | |
|             b[offset++] = (byte)((iValue >>> 24) & 0xff);
 | |
|         }
 | |
| 
 | |
|         private static final void PERM_OP(int a, int b, int n, int m, int results[]) {
 | |
|             int t;
 | |
| 
 | |
|             t = ((a >>> n) ^ b) & m;
 | |
|             a ^= t << n;
 | |
|             b ^= t;
 | |
| 
 | |
|             results[0] = a;
 | |
|             results[1] = b;
 | |
|         }
 | |
| 
 | |
|         private static final int HPERM_OP(int a, int n, int m) {
 | |
|             int t;
 | |
| 
 | |
|             t = ((a << (16 - n)) ^ a) & m;
 | |
|             a = a ^ t ^ (t >>> (16 - n));
 | |
| 
 | |
|             return (a);
 | |
|         }
 | |
| 
 | |
|         private static int[] des_set_key(byte key[]) {
 | |
|             int schedule[] = new int[ITERATIONS * 2];
 | |
| 
 | |
|             int c = fourBytesToInt(key, 0);
 | |
|             int d = fourBytesToInt(key, 4);
 | |
| 
 | |
|             int results[] = new int[2];
 | |
| 
 | |
|             PERM_OP(d, c, 4, 0x0f0f0f0f, results);
 | |
|             d = results[0];
 | |
|             c = results[1];
 | |
| 
 | |
|             c = HPERM_OP(c, -2, 0xcccc0000);
 | |
|             d = HPERM_OP(d, -2, 0xcccc0000);
 | |
| 
 | |
|             PERM_OP(d, c, 1, 0x55555555, results);
 | |
|             d = results[0];
 | |
|             c = results[1];
 | |
| 
 | |
|             PERM_OP(c, d, 8, 0x00ff00ff, results);
 | |
|             c = results[0];
 | |
|             d = results[1];
 | |
| 
 | |
|             PERM_OP(d, c, 1, 0x55555555, results);
 | |
|             d = results[0];
 | |
|             c = results[1];
 | |
| 
 | |
|             d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) | ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4));
 | |
|             c &= 0x0fffffff;
 | |
| 
 | |
|             int s, t;
 | |
|             int j = 0;
 | |
| 
 | |
|             for (int i = 0; i < ITERATIONS; i++) {
 | |
|                 if (shifts2[i]) {
 | |
|                     c = (c >>> 2) | (c << 26);
 | |
|                     d = (d >>> 2) | (d << 26);
 | |
|                 } else {
 | |
|                     c = (c >>> 1) | (c << 27);
 | |
|                     d = (d >>> 1) | (d << 27);
 | |
|                 }
 | |
| 
 | |
|                 c &= 0x0fffffff;
 | |
|                 d &= 0x0fffffff;
 | |
| 
 | |
|                 s = skb[0][(c) & 0x3f] | skb[1][((c >>> 6) & 0x03) | ((c >>> 7) & 0x3c)]
 | |
|                         | skb[2][((c >>> 13) & 0x0f) | ((c >>> 14) & 0x30)]
 | |
|                         | skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) | ((c >>> 22) & 0x38)];
 | |
| 
 | |
|                 t = skb[4][(d) & 0x3f] | skb[5][((d >>> 7) & 0x03) | ((d >>> 8) & 0x3c)]
 | |
|                         | skb[6][(d >>> 15) & 0x3f]
 | |
|                         | skb[7][((d >>> 21) & 0x0f) | ((d >>> 22) & 0x30)];
 | |
| 
 | |
|                 schedule[j++] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
 | |
|                 s = ((s >>> 16) | (t & 0xffff0000));
 | |
| 
 | |
|                 s = (s << 4) | (s >>> 28);
 | |
|                 schedule[j++] = s & 0xffffffff;
 | |
|             }
 | |
|             return (schedule);
 | |
|         }
 | |
| 
 | |
|         private static final int D_ENCRYPT(int L, int R, int S, int E0, int E1, int s[]) {
 | |
|             int t, u, v;
 | |
| 
 | |
|             v = R ^ (R >>> 16);
 | |
|             u = v & E0;
 | |
|             v = v & E1;
 | |
|             u = (u ^ (u << 16)) ^ R ^ s[S];
 | |
|             t = (v ^ (v << 16)) ^ R ^ s[S + 1];
 | |
|             t = (t >>> 4) | (t << 28);
 | |
| 
 | |
|             L ^= SPtrans[1][(t) & 0x3f] | SPtrans[3][(t >>> 8) & 0x3f]
 | |
|                     | SPtrans[5][(t >>> 16) & 0x3f] | SPtrans[7][(t >>> 24) & 0x3f]
 | |
|                     | SPtrans[0][(u) & 0x3f] | SPtrans[2][(u >>> 8) & 0x3f]
 | |
|                     | SPtrans[4][(u >>> 16) & 0x3f] | SPtrans[6][(u >>> 24) & 0x3f];
 | |
| 
 | |
|             return (L);
 | |
|         }
 | |
| 
 | |
|         private static final int[] body(int schedule[], int Eswap0, int Eswap1) {
 | |
|             int left = 0;
 | |
|             int right = 0;
 | |
|             int t = 0;
 | |
| 
 | |
|             for (int j = 0; j < 25; j++) {
 | |
|                 for (int i = 0; i < ITERATIONS * 2; i += 4) {
 | |
|                     left = D_ENCRYPT(left, right, i, Eswap0, Eswap1, schedule);
 | |
|                     right = D_ENCRYPT(right, left, i + 2, Eswap0, Eswap1, schedule);
 | |
|                 }
 | |
|                 t = left;
 | |
|                 left = right;
 | |
|                 right = t;
 | |
|             }
 | |
| 
 | |
|             t = right;
 | |
| 
 | |
|             right = (left >>> 1) | (left << 31);
 | |
|             left = (t >>> 1) | (t << 31);
 | |
| 
 | |
|             left &= 0xffffffff;
 | |
|             right &= 0xffffffff;
 | |
| 
 | |
|             int results[] = new int[2];
 | |
| 
 | |
|             PERM_OP(right, left, 1, 0x55555555, results);
 | |
|             right = results[0];
 | |
|             left = results[1];
 | |
| 
 | |
|             PERM_OP(left, right, 8, 0x00ff00ff, results);
 | |
|             left = results[0];
 | |
|             right = results[1];
 | |
| 
 | |
|             PERM_OP(right, left, 2, 0x33333333, results);
 | |
|             right = results[0];
 | |
|             left = results[1];
 | |
| 
 | |
|             PERM_OP(left, right, 16, 0x0000ffff, results);
 | |
|             left = results[0];
 | |
|             right = results[1];
 | |
| 
 | |
|             PERM_OP(right, left, 4, 0x0f0f0f0f, results);
 | |
|             right = results[0];
 | |
|             left = results[1];
 | |
| 
 | |
|             int out[] = new int[2];
 | |
| 
 | |
|             out[0] = left;
 | |
|             out[1] = right;
 | |
| 
 | |
|             return (out);
 | |
|         }
 | |
| 
 | |
|         public static final String crypt(String salt, String original) {
 | |
|             while (salt.length() < 2)
 | |
|                 salt += "A";
 | |
| 
 | |
|             StringBuffer buffer = new StringBuffer("             ");
 | |
| 
 | |
|             char charZero = salt.charAt(0);
 | |
|             char charOne = salt.charAt(1);
 | |
| 
 | |
|             buffer.setCharAt(0, charZero);
 | |
|             buffer.setCharAt(1, charOne);
 | |
| 
 | |
|             int Eswap0 = con_salt[(int)charZero];
 | |
|             int Eswap1 = con_salt[(int)charOne] << 4;
 | |
| 
 | |
|             byte key[] = new byte[8];
 | |
| 
 | |
|             for (int i = 0; i < key.length; i++)
 | |
|                 key[i] = (byte)0;
 | |
| 
 | |
|             for (int i = 0; i < key.length && i < original.length(); i++) {
 | |
|                 int iChar = (int)original.charAt(i);
 | |
| 
 | |
|                 key[i] = (byte)(iChar << 1);
 | |
|             }
 | |
| 
 | |
|             int schedule[] = des_set_key(key);
 | |
|             int out[] = body(schedule, Eswap0, Eswap1);
 | |
| 
 | |
|             byte b[] = new byte[9];
 | |
| 
 | |
|             intToFourBytes(out[0], b, 0);
 | |
|             intToFourBytes(out[1], b, 4);
 | |
|             b[8] = 0;
 | |
| 
 | |
|             for (int i = 2, y = 0, u = 0x80; i < 13; i++) {
 | |
|                 for (int j = 0, c = 0; j < 6; j++) {
 | |
|                     c <<= 1;
 | |
| 
 | |
|                     if (((int)b[y] & u) != 0) c |= 1;
 | |
| 
 | |
|                     u >>>= 1;
 | |
| 
 | |
|                     if (u == 0) {
 | |
|                         y++;
 | |
|                         u = 0x80;
 | |
|                     }
 | |
|                     buffer.setCharAt(i, (char)cov_2char[c]);
 | |
|                 }
 | |
|             }
 | |
|             return (buffer.toString());
 | |
|         }
 | |
| 
 | |
|         public static void main(String args[]) {
 | |
|             if (args.length >= 2) {
 | |
|                 System.out.println("[" + args[0] + "] [" + args[1] + "] => ["
 | |
|                         + jcrypt.crypt(args[0], args[1]) + "]");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
|     public static class Hash {
 | |
|         private Hash() {
 | |
|         }
 | |
| 
 | |
|         private static final byte[] getBytes(String s) {
 | |
|             try {
 | |
|                 return s.getBytes(UTF_8);
 | |
|             } catch (UnsupportedEncodingException e) {
 | |
|                 return s.getBytes();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String crypt(String original, String salt) {
 | |
|             return jcrypt.crypt(salt, original);
 | |
|         }
 | |
| 
 | |
|         public static final byte[] md5_bytes(String original) {
 | |
|             MessageDigest md;
 | |
|             try {
 | |
|                 md = MessageDigest.getInstance("MD5");
 | |
|             } catch (NoSuchAlgorithmException e) {
 | |
|                 throw new AssertionError("MD5 n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|             return md.digest(getBytes(original));
 | |
|         }
 | |
| 
 | |
|         public static final String md5(String original) {
 | |
|             return Base64.encodeBytes(md5_bytes(original));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] smd5_bytes(String original, byte[] salt) {
 | |
|             if (salt == null) salt = new byte[0];
 | |
|             MessageDigest md;
 | |
|             try {
 | |
|                 md = MessageDigest.getInstance("MD5");
 | |
|             } catch (NoSuchAlgorithmException e) {
 | |
|                 throw new AssertionError("MD5 n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|             md.update(getBytes(original));
 | |
|             md.update(salt);
 | |
|             byte[] tmpdigest = md.digest();
 | |
|             byte[] digest = new byte[tmpdigest.length + salt.length];
 | |
|             System.arraycopy(tmpdigest, 0, digest, 0, tmpdigest.length);
 | |
|             System.arraycopy(salt, 0, digest, tmpdigest.length, salt.length);
 | |
|             return digest;
 | |
|         }
 | |
| 
 | |
|         public static final String smd5(String original, byte[] salt) {
 | |
|             return Base64.encodeBytes(smd5_bytes(original, salt));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] sha_bytes(String original) {
 | |
|             MessageDigest md;
 | |
|             try {
 | |
|                 md = MessageDigest.getInstance("SHA-1");
 | |
|             } catch (NoSuchAlgorithmException e) {
 | |
|                 throw new AssertionError("SHA-1 n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|             return md.digest(getBytes(original));
 | |
|         }
 | |
| 
 | |
|         public static final String sha(String original) {
 | |
|             return Base64.encodeBytes(sha_bytes(original));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] ssha_bytes(String original, byte[] salt) {
 | |
|             if (salt == null) salt = new byte[0];
 | |
|             MessageDigest md;
 | |
|             try {
 | |
|                 md = MessageDigest.getInstance("SHA-1");
 | |
|             } catch (NoSuchAlgorithmException e) {
 | |
|                 throw new AssertionError("SHA-1 n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|             md.update(getBytes(original));
 | |
|             md.update(salt);
 | |
|             byte[] tmpdigest = md.digest();
 | |
|             byte[] digest = new byte[tmpdigest.length + salt.length];
 | |
|             System.arraycopy(tmpdigest, 0, digest, 0, tmpdigest.length);
 | |
|             System.arraycopy(salt, 0, digest, tmpdigest.length, salt.length);
 | |
|             return digest;
 | |
|         }
 | |
| 
 | |
|         public static final String ssha(String original, byte[] salt) {
 | |
|             return Base64.encodeBytes(ssha_bytes(original, salt));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] ntHash_bytes(String password) {
 | |
|             try {
 | |
|                 return new MD4().digest(password.getBytes("UTF-16LE"));
 | |
|             } catch (UnsupportedEncodingException e) {
 | |
|                 throw new AssertionError("UTF-16LE n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String ntlm(String password) {
 | |
|             return toHex(ntHash_bytes(password));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] lmHash_bytes(String password) {
 | |
|             try {
 | |
|                 byte[] oemPassword = password.toUpperCase().getBytes("US-ASCII");
 | |
|                 int length = Math.min(oemPassword.length, 14);
 | |
|                 byte[] keys = new byte[14];
 | |
|                 System.arraycopy(oemPassword, 0, keys, 0, length);
 | |
|                 byte[] magic = "KGS!@#$%".getBytes("US-ASCII");
 | |
|                 byte[] key1 = new byte[7];
 | |
|                 System.arraycopy(keys, 0, key1, 0, 7);
 | |
|                 byte[] hash1 = new DES(key1).encrypt(magic);
 | |
|                 byte[] key2 = new byte[7];
 | |
|                 System.arraycopy(keys, 7, key2, 0, 7);
 | |
|                 byte[] hash2 = new DES(key2).encrypt(magic);
 | |
|                 byte[] hash = new byte[16];
 | |
|                 System.arraycopy(hash1, 0, hash, 0, 8);
 | |
|                 System.arraycopy(hash2, 0, hash, 8, 8);
 | |
|                 return hash;
 | |
|             } catch (UnsupportedEncodingException e) {
 | |
|                 throw new AssertionError("US-ASCII n'est pas disponible: " + getSummary(e));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String lm(String password) {
 | |
|             return toHex(lmHash_bytes(password));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class Salt {
 | |
|         public static final String getCryptSalt(String pw) {
 | |
|             if (pw == null) return null;
 | |
|             if (strSubstr(pw, 0, 7).equalsIgnoreCase("{crypt}")) pw = strSubstr(pw, 7);
 | |
|             return strSubstr(pw, 0, 2);
 | |
|         }
 | |
| 
 | |
|         public static final byte[] getSmd5Salt(byte[] digest) {
 | |
|             if (digest == null) return null;
 | |
|             if (digest.length <= 16) return new byte[0];
 | |
|             byte[] salt = new byte[digest.length - 16];
 | |
|             System.arraycopy(digest, 16, salt, 0, salt.length);
 | |
|             return salt;
 | |
|         }
 | |
| 
 | |
|         public static final byte[] getSmd5Salt(String pw) {
 | |
|             if (pw == null) return null;
 | |
|             if (strSubstr(pw, 0, 6).equalsIgnoreCase("{smd5}")) pw = strSubstr(pw, 6);
 | |
|             try {
 | |
|                 return getSmd5Salt(Base64.decode(pw));
 | |
|             } catch (IllegalArgumentException e) {
 | |
|                 return null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final byte[] getSshaSalt(byte[] digest) {
 | |
|             if (digest == null) return null;
 | |
|             if (digest.length <= 20) return new byte[0];
 | |
|             byte[] salt = new byte[digest.length - 20];
 | |
|             System.arraycopy(digest, 20, salt, 0, salt.length);
 | |
|             return salt;
 | |
|         }
 | |
| 
 | |
|         public static final byte[] getSshaSalt(String pw) {
 | |
|             if (pw == null) return null;
 | |
|             if (strSubstr(pw, 0, 6).equalsIgnoreCase("{ssha}")) pw = strSubstr(pw, 6);
 | |
|             try {
 | |
|                 return getSshaSalt(Base64.decode(pw));
 | |
|             } catch (IllegalArgumentException e) {
 | |
|                 return null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String[] DEFAULT_CRYPT_SALT_SECTIONS = new String[] {
 | |
|                 PasswordGenerator.UPPER,
 | |
|                 PasswordGenerator.LOWER,
 | |
|                 PasswordGenerator.NUMBERS};
 | |
| 
 | |
|         private static final SecureRandom newSecureRandom() {
 | |
|             try {
 | |
|                 return SecureRandom.getInstance("SHA1PRNG");
 | |
|             } catch (NoSuchAlgorithmException e) {
 | |
|                 return new SecureRandom();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static final SecureRandom DEFAULT_RAND = newSecureRandom();
 | |
| 
 | |
|         private static final int DEFAULT_BINARY_SALT_LENGTH = 20;
 | |
| 
 | |
|         private static final Salt instance = new Salt();
 | |
| 
 | |
|         public static final Salt getInstance() {
 | |
|             return instance;
 | |
|         }
 | |
| 
 | |
|         public Salt(Random rand, String[] cryptSaltSections, int binarySaltLength) {
 | |
|             if (rand == null) rand = DEFAULT_RAND;
 | |
|             if (cryptSaltSections == null) cryptSaltSections = DEFAULT_CRYPT_SALT_SECTIONS;
 | |
|             if (binarySaltLength <= 0) binarySaltLength = DEFAULT_BINARY_SALT_LENGTH;
 | |
|             this.rand = rand;
 | |
|             this.cryptSaltSections = cryptSaltSections;
 | |
|             this.binarySaltLength = binarySaltLength;
 | |
|         }
 | |
| 
 | |
|         public Salt() {
 | |
|             this(null, null, -1);
 | |
|         }
 | |
| 
 | |
|         private Random rand;
 | |
| 
 | |
|         private String[] cryptSaltSections;
 | |
| 
 | |
|         public String newCryptSalt() {
 | |
|             return PasswordGenerator.generate(2, cryptSaltSections, rand);
 | |
|         }
 | |
| 
 | |
|         private int binarySaltLength;
 | |
| 
 | |
|         public byte[] newBinarySalt() {
 | |
|             byte[] salt = new byte[binarySaltLength];
 | |
|             rand.nextBytes(salt);
 | |
|             return salt;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class Password {
 | |
|         public static final String CLEARTEXT = "", CRYPT = "CRYPT", MD5 = "MD5", SMD5 = "SMD5",
 | |
|                 SHA = "SHA", XSHA = "XSHA", SSHA = "SSHA";
 | |
| 
 | |
|         public static final String DEFAULT_SCHEME = SSHA;
 | |
| 
 | |
|         public static final List<String> VALID_SCHEMES = Arrays.asList(new String[] {
 | |
|                 CLEARTEXT,
 | |
|                 CRYPT,
 | |
|                 MD5,
 | |
|                 SMD5,
 | |
|                 SHA,
 | |
|                 SSHA});
 | |
| 
 | |
|         private static final Pattern NORMALIZED_FORMAT = Pattern.compile("\\{.+\\}.+");
 | |
| 
 | |
|         public static final boolean isNormalizedFormat(String pw) {
 | |
|             return pw != null && NORMALIZED_FORMAT.matcher(pw).matches();
 | |
|         }
 | |
| 
 | |
|         private static final Pattern XSHA_FORMAT = Pattern.compile("[A-Fa-f0-9]{40}");
 | |
| 
 | |
|         public static final boolean isXshaFormat(String pw) {
 | |
|             return pw != null && XSHA_FORMAT.matcher(pw).matches();
 | |
|         }
 | |
| 
 | |
|         public static final String getNormalizedScheme(String pw, boolean parseXsha) {
 | |
|             if (pw == null) return null;
 | |
|             if (isNormalizedFormat(pw)) {
 | |
|                 int p = pw.indexOf('}');
 | |
|                 return strSubstr(pw, 1, p).toUpperCase();
 | |
|             } else if (parseXsha && isXshaFormat(pw)) {
 | |
|                 return XSHA;
 | |
|             } else {
 | |
|                 return CLEARTEXT;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String getNormalizedScheme(String pw) {
 | |
|             return getNormalizedScheme(pw, false);
 | |
|         }
 | |
| 
 | |
|         public static final String getNormalizedPassword(String pw, boolean parseXsha) {
 | |
|             if (pw == null) return null;
 | |
|             if (isNormalizedFormat(pw)) {
 | |
|                 int p = pw.indexOf('}');
 | |
|                 return strSubstr(pw, p + 1);
 | |
|             } else if (parseXsha && isXshaFormat(pw)) {
 | |
|                 return pw;
 | |
|             } else {
 | |
|                 return pw;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static final String getNormalizedPassword(String pw) {
 | |
|             return getNormalizedPassword(pw, false);
 | |
|         }
 | |
| 
 | |
|         public static final boolean isClearScheme(String pw, boolean parseXsha) {
 | |
|             String scheme = getNormalizedScheme(pw, parseXsha);
 | |
|             return strIsempty(scheme) || CLEARTEXT.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public static final boolean isClearScheme(String pw) {
 | |
|             return isClearScheme(pw, false);
 | |
|         }
 | |
| 
 | |
|         public static final boolean isCryptScheme(String pw) {
 | |
|             return CRYPT.equals(getNormalizedScheme(pw));
 | |
|         }
 | |
| 
 | |
|         public static final boolean isMd5Scheme(String pw) {
 | |
|             return MD5.equals(getNormalizedScheme(pw));
 | |
|         }
 | |
| 
 | |
|         public static final boolean isSmd5Scheme(String pw) {
 | |
|             return SMD5.equals(getNormalizedScheme(pw));
 | |
|         }
 | |
| 
 | |
|         public static final boolean isShaScheme(String pw) {
 | |
|             return SHA.equals(getNormalizedScheme(pw));
 | |
|         }
 | |
| 
 | |
|         public static final boolean isXshaScheme(String pw) {
 | |
|             return XSHA.equals(getNormalizedScheme(pw, true));
 | |
|         }
 | |
| 
 | |
|         public static final boolean isSshaScheme(String pw) {
 | |
|             return SSHA.equals(getNormalizedScheme(pw));
 | |
|         }
 | |
| 
 | |
|         public static final boolean validate(String clear, String normalized) {
 | |
|             return new Password(normalized).validate(clear);
 | |
|         }
 | |
| 
 | |
|         private Salt saltGenerator = Salt.getInstance();
 | |
| 
 | |
|         public void setSaltGenerator(Salt saltGenerator) {
 | |
|             if (saltGenerator == null) saltGenerator = Salt.getInstance();
 | |
|             this.saltGenerator = saltGenerator;
 | |
|         }
 | |
| 
 | |
|         public Password(String clear, String scheme, String crypted, String lmhash, String ntlmhash) {
 | |
|             reset(true);
 | |
|             setClear(clear);
 | |
|             setScheme(scheme);
 | |
|             this.crypted = crypted;
 | |
|             this.lmHash = lmhash;
 | |
|             this.ntlmHash = ntlmhash;
 | |
|         }
 | |
| 
 | |
|         public Password() {
 | |
|             reset(true);
 | |
|         }
 | |
| 
 | |
|         public Password(String normalized) {
 | |
|             this();
 | |
|             setNormalized(normalized);
 | |
|         }
 | |
| 
 | |
|         public Password(String clear, String scheme) {
 | |
|             this();
 | |
|             setClear(clear);
 | |
|             setScheme(scheme);
 | |
|         }
 | |
| 
 | |
|         protected boolean parseXsha;
 | |
| 
 | |
|         public void setParseXsha(boolean parseXsha) {
 | |
|             this.parseXsha = parseXsha;
 | |
|         }
 | |
| 
 | |
|         protected String scheme;
 | |
| 
 | |
|         public String getScheme() {
 | |
|             return scheme;
 | |
|         }
 | |
| 
 | |
|         public void setScheme(String scheme) {
 | |
|             if (scheme == null) scheme = DEFAULT_SCHEME;
 | |
|             if (!strEquals(this.scheme, scheme)) {
 | |
|                 this.scheme = scheme;
 | |
|                 crypted = normalized = ntlmHash = lmHash = null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public boolean isClearScheme() {
 | |
|             return strIsempty(scheme) || CLEARTEXT.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isCryptScheme() {
 | |
|             return CRYPT.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isMd5Scheme() {
 | |
|             return MD5.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isSmd5Scheme() {
 | |
|             return SMD5.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isShaScheme() {
 | |
|             return SHA.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isXshaScheme() {
 | |
|             return XSHA.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         public boolean isSshaScheme() {
 | |
|             return SSHA.equals(scheme);
 | |
|         }
 | |
| 
 | |
|         private final void reset(boolean resetScheme) {
 | |
|             if (resetScheme || scheme == null) scheme = DEFAULT_SCHEME;
 | |
|             clear = crypted = normalized = lmHash = ntlmHash = null;
 | |
|         }
 | |
| 
 | |
|         protected String clear;
 | |
| 
 | |
|         public boolean hasClear() {
 | |
|             return clear != null;
 | |
|         }
 | |
| 
 | |
|         protected String randomCryptSalt() {
 | |
|             return saltGenerator.newCryptSalt();
 | |
|         }
 | |
| 
 | |
|         protected byte[] randomBinarySalt() {
 | |
|             return saltGenerator.newBinarySalt();
 | |
|         }
 | |
| 
 | |
|         public static class NotAvailableException extends Exception {
 | |
|             private static final long serialVersionUID = 1L;
 | |
| 
 | |
|             public static final String DEFAULT_MESSAGE = "Mot de passe en clair non disponible";
 | |
| 
 | |
|             public NotAvailableException(String message) {
 | |
|                 super(message != null? message: DEFAULT_MESSAGE);
 | |
|             }
 | |
| 
 | |
|             public NotAvailableException() {
 | |
|                 this(null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public String getClear() throws NotAvailableException {
 | |
|             if (clear != null || crypted == null) return clear;
 | |
|             throw new NotAvailableException();
 | |
|         }
 | |
| 
 | |
|         public String getClearOrNull() {
 | |
|             return clear;
 | |
|         }
 | |
| 
 | |
|         public Password setClear(String clear) {
 | |
|             reset(false);
 | |
|             this.clear = clear;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setCryptPassword(String pw) {
 | |
|             reset(true);
 | |
|             scheme = CRYPT;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setMd5Password(String pw) {
 | |
|             reset(true);
 | |
|             scheme = MD5;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setSmd5Password(String pw) {
 | |
|             reset(true);
 | |
|             scheme = SMD5;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setShaPassword(String pw) {
 | |
|             reset(true);
 | |
|             scheme = SHA;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setXshaPassword(String pw) {
 | |
|             reset(true);
 | |
|             scheme = XSHA;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setSshaPassword(String pw) {
 | |
|             reset(true);
 | |
|             scheme = SSHA;
 | |
|             crypted = pw;
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         private static final String DISABLED = "*disabled*";
 | |
| 
 | |
|         public boolean isDisabled() {
 | |
|             return !isClearScheme() && strEquals(crypted, DISABLED);
 | |
|         }
 | |
| 
 | |
|         public Password setDisabled(boolean disabled) {
 | |
|             if (disabled && !isClearScheme()) {
 | |
|                 crypted = DISABLED;
 | |
|                 ntlmHash = lmHash = normalized = null;
 | |
|             }
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         protected String crypted;
 | |
| 
 | |
|         public String getCrypted() {
 | |
|             if (isClearScheme()) return clear;
 | |
|             else if (crypted == null) {
 | |
|                 if (isCryptScheme()) crypted = Hash.crypt(clear, randomCryptSalt());
 | |
|                 else if (isMd5Scheme()) crypted = Hash.md5(clear);
 | |
|                 else if (isSmd5Scheme()) crypted = Hash.smd5(clear, randomBinarySalt());
 | |
|                 else if (isShaScheme()) crypted = Hash.sha(clear);
 | |
|                 else if (isXshaScheme()) crypted = toHex(Hash.sha_bytes(clear));
 | |
|                 else if (isSshaScheme()) crypted = Hash.ssha(clear, randomBinarySalt());
 | |
|                 else throw new IllegalStateException("Type de cryptage non reconnu: " + scheme);
 | |
|             }
 | |
|             return crypted;
 | |
|         }
 | |
| 
 | |
|         public String getCryptCrypted() {
 | |
|             if (isCryptScheme()) return getCrypted();
 | |
|             else if (clear != null) return Hash.crypt(clear, randomCryptSalt());
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         public String getMd5Crypted() {
 | |
|             if (isMd5Scheme()) return getCrypted();
 | |
|             else if (clear != null) return Hash.md5(clear);
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         public String getSmd5Crypted() {
 | |
|             if (isSmd5Scheme()) return getCrypted();
 | |
|             else if (clear != null) return Hash.smd5(clear, randomBinarySalt());
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         public String getShaCrypted() {
 | |
|             if (isShaScheme()) return getCrypted();
 | |
|             else if (clear != null) return Hash.sha(clear);
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         public String getXshaCrypted() {
 | |
|             if (isXshaScheme()) return getCrypted();
 | |
|             else if (clear != null) return toHex(Hash.sha_bytes(clear));
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         public String getSshaCrypted() {
 | |
|             if (isSshaScheme()) return getCrypted();
 | |
|             else if (clear != null) return Hash.ssha(clear, randomBinarySalt());
 | |
|             else return null;
 | |
|         }
 | |
| 
 | |
|         protected String normalized;
 | |
| 
 | |
|         public String getNormalized() {
 | |
|             if (normalized == null) {
 | |
|                 if (isClearScheme()) normalized = clear;
 | |
|                 else if (isXshaScheme()) normalized = getCrypted();
 | |
|                 else normalized = "{" + scheme + "}" + getCrypted();
 | |
|             }
 | |
|             return normalized;
 | |
|         }
 | |
| 
 | |
|         public String toString() {
 | |
|             return getNormalized();
 | |
|         }
 | |
| 
 | |
|         public Password setNormalized(String pw, boolean parseXsha) {
 | |
|             reset(true);
 | |
|             if (pw == null) {
 | |
|                 scheme = CLEARTEXT;
 | |
|                 return this;
 | |
|             }
 | |
| 
 | |
|             if (isNormalizedFormat(pw)) {
 | |
|                 int p = pw.indexOf('}');
 | |
|                 scheme = strSubstr(pw, 1, p).toUpperCase();
 | |
|                 crypted = strSubstr(pw, p + 1);
 | |
|             } else if (parseXsha && isXshaFormat(pw)) {
 | |
|                 scheme = XSHA;
 | |
|                 crypted = pw;
 | |
|             } else {
 | |
|                 scheme = CLEARTEXT;
 | |
|                 clear = pw;
 | |
|             }
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         public Password setNormalized(String pw) {
 | |
|             return setNormalized(pw, parseXsha);
 | |
|         }
 | |
| 
 | |
|         private static final String NTLM_DISABLED = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
 | |
| 
 | |
|         protected String ntlmHash;
 | |
| 
 | |
|         public String getNtlmHash() throws NotAvailableException {
 | |
|             if (ntlmHash == null) {
 | |
|                 if (isDisabled()) ntlmHash = NTLM_DISABLED;
 | |
|                 else if (hasClear()) ntlmHash = Hash.ntlm(clear);
 | |
|                 else throw new NotAvailableException();
 | |
|             }
 | |
|             return ntlmHash;
 | |
|         }
 | |
| 
 | |
|         protected String lmHash;
 | |
| 
 | |
|         public String getLmHash() throws NotAvailableException {
 | |
|             if (lmHash == null) {
 | |
|                 if (isDisabled()) lmHash = NTLM_DISABLED;
 | |
|                 else if (hasClear()) lmHash = Hash.lm(clear);
 | |
|                 else throw new NotAvailableException();
 | |
|             }
 | |
|             return lmHash;
 | |
|         }
 | |
| 
 | |
|         public boolean validate(String userPassword) {
 | |
|             getNormalized();
 | |
| 
 | |
|             if (isClearScheme()) {
 | |
|                 return strEquals(strNotnull(this.clear), strNotnull(userPassword));
 | |
|             }
 | |
| 
 | |
|             if (userPassword == null) return false;
 | |
|             if (isCryptScheme()) {
 | |
|                 return Hash.crypt(userPassword, Salt.getCryptSalt(crypted)).equals(crypted);
 | |
|             } else if (isMd5Scheme()) {
 | |
|                 return Hash.md5(userPassword).equals(crypted);
 | |
|             } else if (isSmd5Scheme()) {
 | |
|                 return Hash.smd5(userPassword, Salt.getSmd5Salt(crypted)).equals(crypted);
 | |
|             } else if (isShaScheme()) {
 | |
|                 return Hash.sha(userPassword).equals(crypted);
 | |
|             } else if (isXshaScheme()) {
 | |
|                 return toHex(Hash.sha_bytes(userPassword)).equals(crypted);
 | |
|             } else if (isSshaScheme()) {
 | |
|                 return Hash.ssha(userPassword, Salt.getSshaSalt(crypted)).equals(crypted);
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         public boolean equals(Object obj) {
 | |
|             if (obj == null) return false;
 | |
|             else if (obj instanceof String) {
 | |
|                 String pw = (String)obj;
 | |
|                 if (isNormalizedFormat(pw)) {
 | |
|                     return strEquals(getNormalized(), pw);
 | |
|                 } else return validate((String)obj);
 | |
|             } else if (obj instanceof Password) {
 | |
|                 return strEquals(getNormalized(), ((Password)obj).getNormalized());
 | |
|             }
 | |
|             throw new IllegalArgumentException("Ne peut comparer qu'avec une instance de "
 | |
|                     + getClass() + " (obtenu une " + "instance de " + obj.getClass() + ")");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class PasswordChecker {
 | |
|         public PasswordChecker(int minLen, int minUpper, int minLower, int minAlpha, int minNumber,
 | |
|                 int minSymbol, int minSpecial, boolean allowMultibytes) {
 | |
|             this.minLen = minLen;
 | |
|             this.minUpper = minUpper;
 | |
|             this.minLower = minLower;
 | |
|             this.minAlpha = minAlpha;
 | |
|             this.minNumber = minNumber;
 | |
|             this.minSymbol = minSymbol;
 | |
|             this.minSpecial = minSpecial;
 | |
|             this.allowMultibytes = allowMultibytes;
 | |
|         }
 | |
| 
 | |
|         public PasswordChecker() {
 | |
|             this(MIN_LEN, MIN_UPPER, MIN_LOWER, MIN_ALPHA, MIN_NUMBER, MIN_SYMBOL, MIN_SPECIAL,
 | |
|                     ALLOW_MULTIBYTES);
 | |
|         }
 | |
| 
 | |
|         private int minLen;
 | |
| 
 | |
|         public int getMinLen() {
 | |
|             return minLen;
 | |
|         }
 | |
| 
 | |
|         public void setMinLen(int minLen) {
 | |
|             this.minLen = minLen;
 | |
|         }
 | |
| 
 | |
|         private int minUpper;
 | |
| 
 | |
|         public int getMinUpper() {
 | |
|             return minUpper;
 | |
|         }
 | |
| 
 | |
|         public void setMinUpper(int minUpper) {
 | |
|             this.minUpper = minUpper;
 | |
|         }
 | |
| 
 | |
|         private int minLower;
 | |
| 
 | |
|         public int getMinLower() {
 | |
|             return minLower;
 | |
|         }
 | |
| 
 | |
|         public void setMinLower(int minLower) {
 | |
|             this.minLower = minLower;
 | |
|         }
 | |
| 
 | |
|         private int minAlpha;
 | |
| 
 | |
|         public int getMinAlpha() {
 | |
|             return minAlpha;
 | |
|         }
 | |
| 
 | |
|         public void setMinAlpha(int minAlpha) {
 | |
|             this.minAlpha = minAlpha;
 | |
|         }
 | |
| 
 | |
|         private int minNumber;
 | |
| 
 | |
|         public int getMinNumber() {
 | |
|             return minNumber;
 | |
|         }
 | |
| 
 | |
|         public void setMinNumber(int minNumber) {
 | |
|             this.minNumber = minNumber;
 | |
|         }
 | |
| 
 | |
|         private int minSymbol;
 | |
| 
 | |
|         public int getMinSymbol() {
 | |
|             return minSymbol;
 | |
|         }
 | |
| 
 | |
|         public void setMinSymbol(int minSymbol) {
 | |
|             this.minSymbol = minSymbol;
 | |
|         }
 | |
| 
 | |
|         private int minSpecial;
 | |
| 
 | |
|         public int getMinSpecial() {
 | |
|             return minSpecial;
 | |
|         }
 | |
| 
 | |
|         public void setMinSpecial(int minSpecial) {
 | |
|             this.minSpecial = minSpecial;
 | |
|         }
 | |
| 
 | |
|         private boolean allowMultibytes;
 | |
| 
 | |
|         public boolean isAllowMultibytes() {
 | |
|             return allowMultibytes;
 | |
|         }
 | |
| 
 | |
|         public void setAllowMultibytes(boolean allowMultibytes) {
 | |
|             this.allowMultibytes = allowMultibytes;
 | |
|         }
 | |
| 
 | |
|         /**
 | |
|          * Obtenir une description des caractéristiques du mot de passe. La chaine retournée est de
 | |
|          * la forme '$prefix doit faire au moins N caractères, et contenir au moins 2 lettres, 2
 | |
|          * chiffres ou caractères spéciaux'.
 | |
|          * <p>
 | |
|          * Les valeurs actualXxx sont les nombres effectifs de caractères de chaque classe, ou -1 si
 | |
|          * leur valeur doit être ignorée. Si le nombre effectif est satisfaisant, cette
 | |
|          * caractéristique n'est pas mentionnée. hasMultibytes==<code>true</code> si le mot de passe
 | |
|          * contient des caractères qui doivent être encodés sur plusieurs octets en UTF-8.
 | |
|          * </p>
 | |
|          */
 | |
|         public String getQualityDescription(String prefix, int actualLen, int actualUpper,
 | |
|                 int actualLower, int actualAlpha, int actualNumber, int actualSymbol,
 | |
|                 int actualSpecial, boolean hasMultibytes) {
 | |
|             if (prefix == null) prefix = "Le mot de passe";
 | |
|             if (minLen <= 0 && minUpper <= 0 && minLower <= 0 && minAlpha <= 0 && minNumber <= 0
 | |
|                     && minSymbol <= 0 && minSpecial <= 0 && allowMultibytes) {
 | |
|                 return prefix + " n'as pas de restrictions particulières";
 | |
|             }
 | |
|             StringBuilder sb = new StringBuilder();
 | |
|             sb.append(prefix);
 | |
|             boolean mb = false;
 | |
|             if (!allowMultibytes && hasMultibytes) {
 | |
|                 sb.append(" ne doit pas contenir de caractères accentués");
 | |
|                 mb = true;
 | |
|             }
 | |
|             if (mb) sb.append(", doit ");
 | |
|             else sb.append(" doit ");
 | |
|             String ccPrefix;
 | |
|             if (minLen > 0 && (actualLen == -1 || actualLen < minLen)) {
 | |
|                 sb.append("faire au moins ");
 | |
|                 sb.append(minLen);
 | |
|                 sb.append(" caractères");
 | |
|                 ccPrefix = ", et contenir au moins";
 | |
|             } else {
 | |
|                 sb.append("contenir au moins");
 | |
|                 ccPrefix = "";
 | |
|             }
 | |
|             boolean first = true;
 | |
|             if (minUpper > 0 && (actualUpper == -1 || actualUpper < minUpper)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minUpper);
 | |
|                 if (minUpper > 1) sb.append(" lettres majuscules");
 | |
|                 else sb.append(" lettre majuscule");
 | |
|                 first = false;
 | |
|             }
 | |
|             if (minLower > 0 && (actualLower == -1 || actualLower < minLower)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minLower);
 | |
|                 if (minLower > 1) sb.append(" lettres minuscules");
 | |
|                 else sb.append(" lettre minuscule");
 | |
|                 first = false;
 | |
|             }
 | |
|             if (minAlpha > 0 && (actualAlpha == -1 || actualAlpha < minAlpha)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minAlpha);
 | |
|                 if (minAlpha > 1) sb.append(" lettres");
 | |
|                 else sb.append(" lettre");
 | |
|                 first = false;
 | |
|             }
 | |
|             if (minNumber > 0 && (actualNumber == -1 || actualNumber < minNumber)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minNumber);
 | |
|                 if (minNumber > 1) sb.append(" chiffres");
 | |
|                 else sb.append(" chiffre");
 | |
|                 first = false;
 | |
|             }
 | |
|             if (minSymbol > 0 && (actualSymbol == -1 || actualSymbol < minSymbol)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minSymbol);
 | |
|                 if (minSymbol > 1) sb.append(" caractères spéciaux");
 | |
|                 else sb.append(" caractère spécial");
 | |
|                 first = false;
 | |
|             }
 | |
|             if (minSpecial > 0 && (actualSpecial == -1 || actualSpecial < minSpecial)) {
 | |
|                 if (first) sb.append(ccPrefix);
 | |
|                 else sb.append(",");
 | |
|                 sb.append(" ");
 | |
|                 sb.append(minSpecial);
 | |
|                 if (minSpecial > 1) sb.append(" chiffres ou caractères spéciaux");
 | |
|                 else sb.append(" chiffre ou caractère spécial");
 | |
|                 first = false;
 | |
|             }
 | |
|             return sb.toString();
 | |
|         }
 | |
| 
 | |
|         public String getQualityDescription(String prefix) {
 | |
|             return getQualityDescription(prefix, -1, -1, -1, -1, -1, -1, -1, false);
 | |
|         }
 | |
| 
 | |
|         private static final Pattern RE_NOT_UPPER = Pattern.compile("[^A-Z]");
 | |
| 
 | |
|         private static final Pattern RE_NOT_LOWER = Pattern.compile("[^a-z]");
 | |
| 
 | |
|         private static final Pattern RE_NOT_ALPHA = Pattern.compile("[^a-zA-Z]");
 | |
| 
 | |
|         private static final Pattern RE_NOT_NUMBER = Pattern.compile("[^0-9]");
 | |
| 
 | |
|         private static final Pattern RE_NOT_SYMBOL = Pattern.compile("[a-zA-Z0-9]");
 | |
| 
 | |
|         private static final Pattern RE_NOT_SPECIAL = Pattern.compile("[a-zA-Z]");
 | |
| 
 | |
|         /**
 | |
|          * Vérifier que le mot de spécifié est de qualité.
 | |
|          * 
 | |
|          * @return null si le mot de passe est correct. Sinon, retourner un message qui indique ce
 | |
|          *         qui ne va pas.
 | |
|          */
 | |
|         public String validateQuality(String password) {
 | |
|             password = strNotnull(password);
 | |
|             String upper = RE_NOT_UPPER.matcher(password).replaceAll("");
 | |
|             String lower = RE_NOT_LOWER.matcher(password).replaceAll("");
 | |
|             String alpha = RE_NOT_ALPHA.matcher(password).replaceAll("");
 | |
|             String number = RE_NOT_NUMBER.matcher(password).replaceAll("");
 | |
|             String symbol = RE_NOT_SYMBOL.matcher(password).replaceAll("");
 | |
|             String special = RE_NOT_SPECIAL.matcher(password).replaceAll("");
 | |
|             int nbChars = password.length();
 | |
|             int nbBytes;
 | |
|             try {
 | |
|                 byte[] passwordBytes = password.getBytes(UTF_8);
 | |
|                 nbBytes = passwordBytes.length;
 | |
|             } catch (UnsupportedEncodingException e) {
 | |
|                 nbBytes = 0;
 | |
|             }
 | |
|             boolean hasMultibytes = nbChars != nbBytes;
 | |
|             String qualityDescription = getQualityDescription(
 | |
|                     "Il",
 | |
|                     password.length(),
 | |
|                     upper.length(),
 | |
|                     lower.length(),
 | |
|                     alpha.length(),
 | |
|                     number.length(),
 | |
|                     symbol.length(),
 | |
|                     special.length(),
 | |
|                     hasMultibytes);
 | |
|             if (password.length() < minLen) {
 | |
|                 return "Votre mot de passe est trop court (" + qualityDescription + ")";
 | |
|             }
 | |
|             if (!allowMultibytes && hasMultibytes) {
 | |
|                 return "Votre mot de passe ne convient pas (" + qualityDescription + ")";
 | |
|             }
 | |
|             if (upper.length() < minUpper || lower.length() < minLower || alpha.length() < minAlpha
 | |
|                     || number.length() < minNumber || symbol.length() < minSymbol
 | |
|                     || special.length() < minSpecial) {
 | |
|                 return "Votre mot de passe est trop simple (" + qualityDescription + ")";
 | |
|             }
 | |
|             return null;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
|     public static class PasswordGenerator {
 | |
|         public static final String UPPER = "AZERTYUIOPQSDFGHJKLMWXCVBN",
 | |
|                 LOWER = "azertyuiopqsdfghjklmwxcvbn", NUMBERS = "1234567890",
 | |
|                 SYMBOLS = "&\"'(-_)=^$*!:;,?./%+#{[|\\]}";
 | |
| 
 | |
|         public static final String[] DEFAULT_SECTIONS = new String[] {
 | |
|                 UPPER,
 | |
|                 LOWER,
 | |
|                 NUMBERS,
 | |
|                 SYMBOLS};
 | |
| 
 | |
|         public static final int[] DEFAULT_MIN_COUNTS = new int[] {2, 2, 2, 1};
 | |
| 
 | |
|         private static final Random DEFAULT_RAND = new Random();
 | |
| 
 | |
|         private static final PasswordGenerator instance = new PasswordGenerator();
 | |
| 
 | |
|         public static PasswordGenerator getInstance() {
 | |
|             return instance;
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, String[] sections, int[] minCounts,
 | |
|                 Random rand) {
 | |
|             if (sections == null) sections = DEFAULT_SECTIONS;
 | |
|             if (minCounts == null) minCounts = new int[sections.length];
 | |
|             if (sections.length != minCounts.length) {
 | |
|                 throw new IllegalArgumentException("Les tableaux sections et minCounts "
 | |
|                         + "doivent faire la même taille");
 | |
|             } else {
 | |
|                 int[] tmp = new int[minCounts.length];
 | |
|                 System.arraycopy(minCounts, 0, tmp, 0, minCounts.length);
 | |
|                 minCounts = tmp;
 | |
|             }
 | |
|             StringBuffer sb = new StringBuffer();
 | |
|             // int i = 0;
 | |
|             while (true) {
 | |
|                 int index;
 | |
|                 do {
 | |
|                     index = rand.nextInt(sections.length);
 | |
|                 } while (minCounts[index] <= 0);
 | |
|                 String section = sections[index];
 | |
|                 sb.append(section.charAt(rand.nextInt(section.length())));
 | |
|                 minCounts[index]--;
 | |
|                 // i++;
 | |
|                 boolean done = true;
 | |
|                 for (int j = 0; j < minCounts.length; j++) {
 | |
|                     if (minCounts[j] > 0) {
 | |
|                         done = false;
 | |
|                         break;
 | |
|                     }
 | |
|                 }
 | |
|                 if (done) break;
 | |
|             }
 | |
|             while (sb.length() < minLen) {
 | |
|                 String section = sections[rand.nextInt(sections.length)];
 | |
|                 sb.append(section.charAt(rand.nextInt(section.length())));
 | |
|             }
 | |
|             return sb.toString();
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, String[] sections, int[] minCounts) {
 | |
|             return generate(minLen, sections, minCounts, DEFAULT_RAND);
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, int maxLen, String[] sections,
 | |
|                 int[] minCounts, Random rand) {
 | |
|             int len;
 | |
|             if (minLen > maxLen) {
 | |
|                 len = minLen;
 | |
|                 minLen = maxLen;
 | |
|                 maxLen = len;
 | |
|             }
 | |
|             if (minLen == maxLen) len = minLen;
 | |
|             else len = rand.nextInt(maxLen - minLen) + minLen;
 | |
|             return generate(len, sections, minCounts);
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, int maxLen, String[] sections,
 | |
|                 int[] minCounts) {
 | |
|             return generate(minLen, maxLen, sections, minCounts, DEFAULT_RAND);
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int len, String[] sections, Random rand) {
 | |
|             StringBuffer sb = new StringBuffer();
 | |
|             for (int i = 0; i < len; i++) {
 | |
|                 String section = sections[rand.nextInt(sections.length)];
 | |
|                 sb.append(section.charAt(rand.nextInt(section.length())));
 | |
|             }
 | |
|             return sb.toString();
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int len, String[] sections) {
 | |
|             return generate(len, sections, DEFAULT_RAND);
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, int maxLen, String[] sections, Random rand) {
 | |
|             int len;
 | |
|             if (minLen > maxLen) {
 | |
|                 len = minLen;
 | |
|                 minLen = maxLen;
 | |
|                 maxLen = len;
 | |
|             }
 | |
|             if (minLen == maxLen) len = minLen;
 | |
|             else len = rand.nextInt(maxLen - minLen) + minLen;
 | |
|             return generate(len, sections);
 | |
|         }
 | |
| 
 | |
|         public static final String generate(int minLen, int maxLen, String[] sections) {
 | |
|             return generate(minLen, maxLen, sections, DEFAULT_RAND);
 | |
|         }
 | |
| 
 | |
|         /**
 | |
|          * Génère une chaine de caractère aléatoire d'une taille définie adapté aux mot de passe
 | |
|          *
 | |
|          * @param size Nombre de blocs de 4 caractères à générer
 | |
|          * @param punctuationsNumber Nombre de ponctuations à insérer
 | |
|          * @return Chaine de caractères aléatoires générée
 | |
|          */
 | |
|         public static String generateJk(int size, int punctuationsNumber, Random rand) {
 | |
|             final String CONSONANTS = "bcdfghjklmnpqrstvwxz";
 | |
|             final String VOWELS = "aeiuoy";
 | |
|             final String PUNCTUATIONS = "!:;,?.";
 | |
|             String seed;
 | |
|             // taille minimale de la chaine
 | |
|             if (size < 1) size = 1;
 | |
|             // S'il y a trop de ponctuations à placer
 | |
|             if (punctuationsNumber > size) punctuationsNumber = size;
 | |
|             // préparation d'un constructeur de chaîne
 | |
|             StringBuilder builder = new StringBuilder(size);
 | |
|             String punctuationsUsed = "";
 | |
|             int rnd;
 | |
|             // calcule aléatoirement le caractère à sélectionner
 | |
|             for (int index = 0; index < size * 4; index++) {
 | |
|                 // espace
 | |
|                 //if (index != 0 && index % 4 == 0) {
 | |
|                 //    builder.append(" ");
 | |
|                 //}
 | |
|                 // lettre
 | |
|                 seed = index % 2 == 0 ? CONSONANTS : VOWELS;
 | |
|                 builder.append(
 | |
|                     seed.charAt(
 | |
|                         rand.nextInt(seed.length())
 | |
|                     )
 | |
|                 );
 | |
|                 // ponctuation
 | |
|                 if (punctuationsNumber > 0 && (index + 1) % 4 == 0) {
 | |
|                     rnd = rand.nextInt(size);
 | |
|                     if (punctuationsUsed.length() < punctuationsNumber && rnd <= punctuationsNumber) {
 | |
|                         punctuationsUsed += PUNCTUATIONS.charAt(
 | |
|                             rand.nextInt(PUNCTUATIONS.length())
 | |
|                         );
 | |
|                         builder.append(punctuationsUsed.charAt(punctuationsUsed.length() - 1));
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return builder.toString();
 | |
|         }
 | |
| 
 | |
|         public PasswordGenerator(int minLen, String[] sections, int[] minCounts, Random rand) {
 | |
|             setMinLen(minLen);
 | |
|             setSections(sections);
 | |
|             setMinCounts(minCounts);
 | |
|             setRand(rand);
 | |
|         }
 | |
| 
 | |
|         public PasswordGenerator() {
 | |
|             this(-1, null, null, null);
 | |
|         }
 | |
| 
 | |
|         private int minLen;
 | |
| 
 | |
|         public int getMinLen() {
 | |
|             return minLen;
 | |
|         }
 | |
| 
 | |
|         public void setMinLen(int minLen) {
 | |
|             if (minLen < 0) minLen = MIN_LEN;
 | |
|             this.minLen = minLen;
 | |
|         }
 | |
| 
 | |
|         private String[] sections;
 | |
| 
 | |
|         public String[] getSections() {
 | |
|             return sections;
 | |
|         }
 | |
| 
 | |
|         public void setSections(String[] sections) {
 | |
|             if (sections == null) sections = DEFAULT_SECTIONS;
 | |
|             this.sections = sections;
 | |
|         }
 | |
| 
 | |
|         private int[] minCounts;
 | |
| 
 | |
|         public int[] getMinCounts() {
 | |
|             return minCounts;
 | |
|         }
 | |
| 
 | |
|         public void setMinCounts(int[] minCounts) {
 | |
|             if (minCounts == null) minCounts = DEFAULT_MIN_COUNTS;
 | |
|             this.minCounts = minCounts;
 | |
|         }
 | |
| 
 | |
|         private Random rand;
 | |
| 
 | |
|         public Random getRand() {
 | |
|             return rand;
 | |
|         }
 | |
| 
 | |
|         public void setRand(Random rand) {
 | |
|             if (rand == null) rand = DEFAULT_RAND;
 | |
|             this.rand = rand;
 | |
|         }
 | |
| 
 | |
|         public String generate() {
 | |
|             return generate(minLen, sections, minCounts, rand);
 | |
|         }
 | |
| 
 | |
|         public String generate(int maxLen) {
 | |
|             return generate(minLen, maxLen, sections, minCounts, rand);
 | |
|         }
 | |
| 
 | |
|         public String generateJk(int size, int punctuationsNumber) {
 | |
|             return generateJk(size, punctuationsNumber, rand);
 | |
|         }
 | |
|         public String generateJk(int size) {
 | |
|             return generateJk(size, 1, rand);
 | |
|         }
 | |
|         public String generateJk() {
 | |
|             return generateJk(4, 1, rand);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class AESEnc {
 | |
|         private static final String AES = "AES";
 | |
| 
 | |
|         private static final String CIPHER = "AES/ECB/PKCS5Padding";
 | |
| 
 | |
|         public static final byte[] genkey() throws Exception {
 | |
|             KeyGenerator kg = KeyGenerator.getInstance(AES);
 | |
|             kg.init(new SecureRandom());
 | |
|             SecretKey key = kg.generateKey();
 | |
|             return key.getEncoded();
 | |
|         }
 | |
| 
 | |
|         public static final String genskey() throws Exception {
 | |
|             return Base64.encodeBytes(genkey());
 | |
|         }
 | |
| 
 | |
|         public static final byte[] genkey(String password, byte[] salt, int iterations)
 | |
|                 throws Exception {
 | |
|             if (salt == null) salt = Salt.getInstance().newBinarySalt();
 | |
|             if (iterations <= 0) iterations = 10000;
 | |
|             SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
 | |
|             SecretKey tmp = factory.generateSecret(new PBEKeySpec(password.toCharArray(), salt,
 | |
|                     iterations, 128));
 | |
|             SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), AES);
 | |
|             return key.getEncoded();
 | |
|         }
 | |
| 
 | |
|         public static final byte[] genkey(String password) throws Exception {
 | |
|             return genkey(password, null, -1);
 | |
|         }
 | |
| 
 | |
|         public static final String genskey(String password, byte[] salt, int iterations)
 | |
|                 throws Exception {
 | |
|             return Base64.encodeBytes(genkey(password, salt, iterations));
 | |
|         }
 | |
| 
 | |
|         public static final String genskey(String password) throws Exception {
 | |
|             return Base64.encodeBytes(genkey(password));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] getKey(String skey) {
 | |
|             return Base64.decode(skey);
 | |
|         }
 | |
| 
 | |
|         public static final String getSkey(byte[] key) {
 | |
|             return Base64.encodeBytes(key, Base64.DONT_BREAK_LINES);
 | |
|         }
 | |
| 
 | |
|         public static final byte[] encrypt(byte[] clear, byte[] key) throws Exception {
 | |
|             if (clear == null) return null;
 | |
|             if (key == null) throw new NullPointerException("key is required");
 | |
| 
 | |
|             Cipher aes = Cipher.getInstance(CIPHER);
 | |
|             aes.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES));
 | |
|             return aes.doFinal(clear);
 | |
|         }
 | |
| 
 | |
|         public static final String sencrypt(String sclear, byte[] key) throws Exception {
 | |
|             if (sclear == null) return null;
 | |
|             byte[] input = sclear.getBytes(UTF_8);
 | |
|             byte[] output = encrypt(input, key);
 | |
|             return Base64.encodeBytes(output, Base64.DONT_BREAK_LINES);
 | |
|         }
 | |
| 
 | |
|         public static final String sencrypt(String sclear, String skey) throws Exception {
 | |
|             return sencrypt(sclear, getKey(skey));
 | |
|         }
 | |
| 
 | |
|         public static final byte[] decrypt(byte[] crypted, byte[] key) throws Exception {
 | |
|             if (crypted == null) return null;
 | |
|             if (key == null) throw new NullPointerException("key is required");
 | |
| 
 | |
|             Cipher aes = Cipher.getInstance(CIPHER);
 | |
|             aes.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, AES));
 | |
|             return aes.doFinal(crypted);
 | |
|         }
 | |
| 
 | |
|         public static final String sdecrypt(String scrypted, byte[] key) throws Exception {
 | |
|             if (scrypted == null) return null;
 | |
|             byte[] input = Base64.decode(scrypted);
 | |
|             byte[] output = decrypt(input, key);
 | |
|             return new String(output, UTF_8);
 | |
|         }
 | |
| 
 | |
|         public static final String sdecrypt(String scrypted, String skey) throws Exception {
 | |
|             return sdecrypt(scrypted, getKey(skey));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     public static class WOJavaMonitorPassword {
 | |
|         public static long myrand() {
 | |
|             long nextLong = ThreadLocalRandom.current().nextLong();
 | |
|             while (nextLong == Long.MIN_VALUE) {
 | |
|                 nextLong = ThreadLocalRandom.current().nextLong();
 | |
|             }
 | |
|             return Math.abs(nextLong);
 | |
|         }
 | |
| 
 | |
|         public static String encryptStringWithKey(String to_be_encrypted, String aKey) {
 | |
|             String encrypted_value = "";
 | |
|             char xdigit[] = { '0' , '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 | |
|             MessageDigest messageDigest;
 | |
| 
 | |
|             try {
 | |
|                 messageDigest = MessageDigest.getInstance("MD5");
 | |
|             } catch (NoSuchAlgorithmException exc) {
 | |
|                 throw new AssertionError("MD5 n'est pas disponible: " + getSummary(exc));
 | |
|             }
 | |
|             if (to_be_encrypted != null) {
 | |
|                 byte digest[];
 | |
|                 byte fudge_constant[];
 | |
|                 try {
 | |
|                     fudge_constant = ("X#@!").getBytes("UTF8");
 | |
|                 } catch (UnsupportedEncodingException uee) {
 | |
|                     fudge_constant = ("X#@!").getBytes();
 | |
|                 }
 | |
|                 byte fudgetoo_part[] = {
 | |
|                         (byte)xdigit[(int)(myrand() % 16)] ,
 | |
|                         (byte)xdigit[(int)(myrand() % 16)] ,
 | |
|                         (byte)xdigit[(int)(myrand() % 16)] ,
 | |
|                         (byte)xdigit[(int)(myrand() % 16)]
 | |
|                 };
 | |
|                 int i = 0;
 | |
| 
 | |
|                 if (aKey != null) {
 | |
|                     try {
 | |
|                         fudgetoo_part = aKey.getBytes("UTF8");
 | |
|                     } catch (UnsupportedEncodingException uee) {
 | |
|                         fudgetoo_part = aKey.getBytes();
 | |
|                     }
 | |
|                 }
 | |
|                 messageDigest.update(fudge_constant);
 | |
|                 try {
 | |
|                     messageDigest.update(to_be_encrypted.getBytes("UTF8"));
 | |
|                 } catch (UnsupportedEncodingException uee) {
 | |
|                     messageDigest.update(to_be_encrypted.getBytes());
 | |
|                 }
 | |
|                 messageDigest.update(fudgetoo_part);
 | |
|                 digest = messageDigest.digest();
 | |
|                 encrypted_value = new String(fudgetoo_part);
 | |
|                 for (i = 0; i < digest.length; i++) {
 | |
|                     int mashed;
 | |
|                     char temp[] = new char[2];
 | |
|                     if (digest[i] < 0) {
 | |
|                         mashed = 127 + ( -1 * digest[i]);
 | |
|                     } else {
 | |
|                         mashed = digest[i];
 | |
|                     }
 | |
|                     temp[0] = xdigit[mashed / 16];
 | |
|                     temp[1] = xdigit[mashed % 16];
 | |
|                     encrypted_value = encrypted_value + (new String(temp));
 | |
|                 }
 | |
|             }
 | |
|             return encrypted_value;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // ------------------------------------------------------------------------
 | |
| 
 | |
|     private Password getPasswordAnySalt(String clear, String scheme, final String anySalt) {
 | |
|         return new Password(clear, scheme) {
 | |
|             @Override
 | |
|             protected String randomCryptSalt() {
 | |
|                 String salt = Salt.getCryptSalt(anySalt);
 | |
|                 if (salt == null) salt = super.randomCryptSalt();
 | |
|                 return salt;
 | |
|             }
 | |
| 
 | |
|             @Override
 | |
|             protected byte[] randomBinarySalt() {
 | |
|                 byte[] salt = null;
 | |
|                 if (isSshaScheme()) salt = Salt.getSshaSalt(anySalt);
 | |
|                 else if (isSmd5Scheme()) salt = Salt.getSmd5Salt(anySalt);
 | |
|                 if (salt == null) salt = super.randomBinarySalt();
 | |
|                 return salt;
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     private Password getPasswordCryptSalt(String clear, String scheme, final String cryptSalt) {
 | |
|         return new Password(clear, scheme) {
 | |
|             @Override
 | |
|             protected String randomCryptSalt() {
 | |
|                 String salt = cryptSalt;
 | |
|                 if (salt == null) salt = super.randomCryptSalt();
 | |
|                 return salt;
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     private Password getPasswordBinarySalt(String clear, String scheme, final byte[] binarySalt) {
 | |
|         return new Password(clear, scheme) {
 | |
|             @Override
 | |
|             protected byte[] randomBinarySalt() {
 | |
|                 byte[] salt = binarySalt;
 | |
|                 if (salt == null) salt = super.randomBinarySalt();
 | |
|                 return salt;
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     private static final void die(String msg, Exception e) {
 | |
|         if (msg != null) System.err.println(msg);
 | |
|         if (e != null) e.printStackTrace(System.err);
 | |
|         System.err.flush();
 | |
|         System.exit(1);
 | |
|     }
 | |
| 
 | |
|     // actions
 | |
|     private static enum EAction {
 | |
|         HASH_PASSWORD, GEN_AESKEY, SHOW_AESKEY, AES_ENCRYPT, AES_DECRYPT;
 | |
|     }
 | |
| 
 | |
|     private static enum EHashAction {
 | |
|         AUTO, CHECK_MATCH, SAME_OR_NEW, NEW;
 | |
|     }
 | |
| 
 | |
|     private static final void checkExisting(String aeskeyfile) {
 | |
|         if (aeskeyfile == null) die("Vous devez spécifier l'option -f", null);
 | |
|         if (!new File(aeskeyfile).exists()) die(aeskeyfile + ": Fichier introuvable", null);
 | |
|     }
 | |
| 
 | |
|     private static final byte[] readAeskeyfile(String aeskeyfile) {
 | |
|         if (aeskeyfile == null) return null;
 | |
|         byte[] aeskey = null;
 | |
|         try {
 | |
|             FileInputStream fis = new FileInputStream(aeskeyfile);
 | |
|             try {
 | |
|                 aeskey = new byte[16];
 | |
|                 fis.read(aeskey);
 | |
|             } finally {
 | |
|                 fis.close();
 | |
|             }
 | |
|         } catch (Exception e) {
 | |
|             die(null, e);
 | |
|         }
 | |
|         return aeskey;
 | |
|     }
 | |
| 
 | |
|     private static final void writeAeskeyfile(String aeskeyfile, byte[] key) {
 | |
|         if (aeskeyfile == null) return;
 | |
|         try {
 | |
|             FileOutputStream fis = new FileOutputStream(aeskeyfile);
 | |
|             try {
 | |
|                 fis.write(key);
 | |
|             } finally {
 | |
|                 fis.close();
 | |
|             }
 | |
|         } catch (Exception e) {
 | |
|             die(null, e);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private static final void printvar(String name, String value, boolean shell) {
 | |
|         StringBuilder sb = new StringBuilder();
 | |
|         if (shell) {
 | |
|             sb.append(name);
 | |
|             sb.append("='");
 | |
|             sb.append(value.replaceAll("'", "'\\\\''"));
 | |
|             sb.append("'");
 | |
|         } else {
 | |
|             sb.append(name);
 | |
|             sb.append(":");
 | |
|             while (sb.length() < 8)
 | |
|                 sb.append(" ");
 | |
|             sb.append(value);
 | |
|         }
 | |
|         println(sb.toString());
 | |
|     }
 | |
| 
 | |
|     private static final boolean isCodEtu(String codEtu) {
 | |
|         if (codEtu == null) return false;
 | |
|         return Pattern.matches("\\d{8}", codEtu);
 | |
|     }
 | |
| 
 | |
|     private static boolean ETU_PASSWORD_GROUPS_LOCKED = true;
 | |
| 
 | |
|     private static final String[] ETU_PASSWORD_GROUPS = new String[] {
 | |
|             //
 | |
|             "jiPV/09lHKI1uz+a9vUpX0yMUIy9YAeIwfHPXoA81ik=",
 | |
|             "Vgrlv+kkWzlYVIUnnL7zUw==",
 | |
|             "QFL4JbN2+rsQn1zMVkS//8MLGz1dxxgI2jHKM3iIrwg=",
 | |
|             "KMCTgO8AerczlcQubrbsQg==",
 | |
|             "iLOWOlwRn6YpEj/ZSJFdUVWzjvESRSv45UXDStJCanM=",
 | |
|             "ktokGgUx93gjSsimKn4BBQ==",
 | |
|             "jiPV/09lHKI1uz+a9vUpX3CXBrQfBiW/OgGD/CIjZBE=",
 | |
|             "yYjWpZXP2EMWp7VZR+0xPA=="};
 | |
| 
 | |
|     private static final void unlockEtuPasswordGroups(String skey) throws Exception {
 | |
|         if (ETU_PASSWORD_GROUPS_LOCKED) {
 | |
|             byte[] key = AESEnc.getKey(skey);
 | |
|             for (int i = 0; i < ETU_PASSWORD_GROUPS.length; i++) {
 | |
|                 ETU_PASSWORD_GROUPS[i] = AESEnc.sdecrypt(ETU_PASSWORD_GROUPS[i], key);
 | |
|             }
 | |
|             ETU_PASSWORD_GROUPS_LOCKED = false;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private static final String getEtuPassword(String codEtu) {
 | |
|         StringBuilder sb = new StringBuilder();
 | |
|         int crc = Integer.valueOf(codEtu);
 | |
|         for (int i = 0; i < ETU_PASSWORD_GROUPS.length; i++) {
 | |
|             String group = ETU_PASSWORD_GROUPS[i];
 | |
|             int grouplen = group.length();
 | |
|             sb.append(group.charAt(crc % grouplen));
 | |
|         }
 | |
|         return sb.toString();
 | |
|     }
 | |
| 
 | |
|     private void run(String[] args) {
 | |
|         if (args.length == 1 && strEquals(args[0], "--help")) {
 | |
|             println("USAGE:" //
 | |
|                     + "\n    upassword -p [-f aeskeyfile] [clear [salts...]]"
 | |
|                     + "\n    upassword -p [-f aeskeyfile] -j JKEY codetu [salts...]"
 | |
|                     + "\n    upassword -p -f aeskeyfile -k crypted [salts...]"
 | |
|                     + "\n    upassword -f aeskeyfile -G [password [salt]]"
 | |
|                     + "\n    upassword -f aeskeyfile -s"
 | |
|                     + "\n    upassword -f aeskeyfile -e clear"
 | |
|                     + "\n    upassword -f aeskeyfile -d crypted"
 | |
|                     + "\n    upassword --batch"
 | |
|                     + "\n\nOPTIONS"
 | |
|                     + "\n    -b, --nb-blocks COUNT"
 | |
|                     + "\n        Indiquer le nombre de blocs de mots de 4 caractères pour la génération"
 | |
|                     + "\n    -p, --hash-password"
 | |
|                     + "\n        Crypter un mot de passe (option par défaut). Si le mot de passe en clair"
 | |
|                     + "\n        et/ou le salt ne sont pas spécifiés, ils sont choisis au hasard."
 | |
|                     + "\n    -m, --salt-check-match-hash"
 | |
|                     + "\n    -n, --salt-same-or-new-hash"
 | |
|                     + "\n        Spécifier le comportement à adopter si les salts qui sont spécifiés sont"
 | |
|                     + "\n        des hashes normalisés."
 | |
|                     + "\n        Avec l'option -m (par défaut), pour chacun des hashes, le salt est"
 | |
|                     + "\n        extrait et le mot de passe en clair est hashé avec ce salt et le scheme"
 | |
|                     + "\n        spécifiés. Si le hash résultant est le même, afficher 'match: true'"
 | |
|                     + "\n        Avec l'option -n, si l'un des hashes correspond au mot de passe en"
 | |
|                     + "\n        clair, alors afficher ce hash. Sinon, faire comme si le mot de passe en"
 | |
|                     + "\n        clair avait été spécifié sans salt et choisir un nouveau salt au hasard."
 | |
|                     + "\n    -j, --clear-is-codetu JKEY"
 | |
|                     + "\n        Indiquer que l'argument clear est un numéro d'étudiant, à partir duquel"
 | |
|                     + "\n        il faut générer le mot de passe. Cette option n'est valide qu'avec -p"
 | |
|                     + "\n    -k, --clear-is-crypted"
 | |
|                     + "\n        Indiquer que l'argument clear doit d'abord être décrypté avec la clé AES"
 | |
|                     + "\n        spécifiée avant utilisation. Cette option n'est valide qu'avec -p"
 | |
|                     + "\n    -G, --aes-genkey"
 | |
|                     + "\n        Générer une clé AES pour utilisation avec les options -s, -e, -d"
 | |
|                     + "\n    -s, --aes-showkey"
 | |
|                     + "\n        Afficher encodée en base64 la clé AES contenue dans le fichier spécifié"
 | |
|                     + "\n    -e, --aes-encrypt"
 | |
|                     + "\n        Crypter un mot de passe avec la clé AES spécifiée"
 | |
|                     + "\n    -d, --aes-decrypt"
 | |
|                     + "\n        Décrypter un mot de passe avec la clé AES spécifiée"
 | |
|                     + "\n    -f, --aes-keyfile"
 | |
|                     + "\n        Spécifier le fichier contenant la clé AES. Cette option est obligatoire"
 | |
|                     + "\n        avec les options -G, -s, -e et -d"
 | |
|                     + "\n    --shell"
 | |
|                     + "\n        Afficher les valeurs pour évaluation par le shell"
 | |
|                     + "\n\nMODE BATCH"
 | |
|                     + "\nUtiliser l'option --batch active le mode batch. Dans ce mode, chaque ligne est"
 | |
|                     + "\nun ensemble d'arguments, comme si on avait lancé le script à plusieurs reprises."
 | |
|                     + "\nL'analyseur est limité: le découpage des arguments est fait sur les espaces."
 | |
|                     + "\nLes lignes commençant par # sont ignorées."
 | |
|                     + "\nSi une ligne commence par --batch-after, alors cette ligne est affichée après"
 | |
|                     + "\nchaque résultat. Ceci permet de générer un script qui peut être évalué."
 | |
|                     + "\n\nVoici un exemple:"
 | |
|                     + "\n    upassword --batch <<EOF"
 | |
|                     + "\n    --batch-after process_password1 args"
 | |
|                     + "\n    --shell"
 | |
|                     + "\n    --shell fixed-password1"
 | |
|                     + "\n    --batch-after process_password2 args"
 | |
|                     + "\n    --shell fixed-password2"
 | |
|                     + "\n    EOF"
 | |
|                     + "\nLe résultat serait quelque chose comme:"
 | |
|                     + "\n    clear='<random-password>'"
 | |
|                     + "\n    ... # toutes les valeurs lm, ntlm, crypt, sha, xsha, ssha, md5, smd5"
 | |
|                     + "\n    process_password1 args"
 | |
|                     + "\n    clear='fixed-password1'"
 | |
|                     + "\n    ... # toutes les valeurs lm, ntlm, crypt, sha, xsha, ssha, md5, smd5"
 | |
|                     + "\n    process_password1 args"
 | |
|                     + "\n    clear='fixed-password2'"
 | |
|                     + "\n    ... # toutes les valeurs lm, ntlm, crypt, sha, xsha, ssha, md5, smd5"
 | |
|                     + "\n    process_password2 args");
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         int nbBlocks = 4;
 | |
|         EAction action = EAction.HASH_PASSWORD;
 | |
|         EHashAction hashAction = EHashAction.AUTO;
 | |
|         boolean codEtu = false, crypted = false, shell = false;
 | |
|         String codEtuKey = null;
 | |
|         String aeskeyfile = null;
 | |
|         int i = 0, max = args.length;
 | |
|         while (i < args.length) {
 | |
|             String arg = args[i];
 | |
|             if ((arg.length() >= 2 && arg.substring(0, 2).equals("-b"))
 | |
|                     || arg.equals("--nb-blocks")) {
 | |
|                 int shift = 1;
 | |
|                 if (arg.equals("-b") || arg.equals("--nb-blocks")) {
 | |
|                     if (args.length > i + 1) {
 | |
|                         nbBlocks = Integer.parseInt(args[i + 1]);
 | |
|                         shift = 2;
 | |
|                     }
 | |
|                 } else {
 | |
|                     nbBlocks = Integer.parseInt(arg.substring(2));
 | |
|                 }
 | |
|                 i += shift;
 | |
|             } else if (arg.equals("-p") || arg.equals("--hash-password")) {
 | |
|                 action = EAction.HASH_PASSWORD;
 | |
|                 i++;
 | |
|             } else if ((arg.length() >= 2 && arg.substring(0, 2).equals("-j"))
 | |
|                     || arg.equals("--clear-is-codetu")) {
 | |
|                 int shift = 1;
 | |
|                 if (arg.equals("-j") || arg.equals("--clear-is-codetu")) {
 | |
|                     if (args.length > i + 1) {
 | |
|                         codEtuKey = args[i + 1];
 | |
|                         shift = 2;
 | |
|                     }
 | |
|                 } else {
 | |
|                     codEtuKey = arg.substring(2);
 | |
|                 }
 | |
|                 i += shift;
 | |
|                 codEtu = true;
 | |
|             } else if (arg.equals("-k") || arg.equals("--clear-is-crypted")) {
 | |
|                 crypted = true;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-m") || arg.equals("--salt-check-match-hash")) {
 | |
|                 hashAction = EHashAction.CHECK_MATCH;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-n") || arg.equals("--salt-same-or-new-hash")) {
 | |
|                 hashAction = EHashAction.SAME_OR_NEW;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-G") || arg.equals("--aes-genkey")) {
 | |
|                 action = EAction.GEN_AESKEY;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-s") || arg.equals("--aes-showkey")) {
 | |
|                 action = EAction.SHOW_AESKEY;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-e") || arg.equals("--aes-encrypt")) {
 | |
|                 action = EAction.AES_ENCRYPT;
 | |
|                 i++;
 | |
|             } else if (arg.equals("-d") || arg.equals("--aes-decrypt")) {
 | |
|                 action = EAction.AES_DECRYPT;
 | |
|                 i++;
 | |
|             } else if ((arg.length() >= 2 && arg.substring(0, 2).equals("-f"))
 | |
|                     || arg.equals("--aes-keyfile")) {
 | |
|                 int shift = 1;
 | |
|                 if (arg.equals("-f") || arg.equals("--aes-keyfile")) {
 | |
|                     if (args.length > i + 1) {
 | |
|                         aeskeyfile = args[i + 1];
 | |
|                         shift = 2;
 | |
|                     }
 | |
|                 } else {
 | |
|                     aeskeyfile = arg.substring(2);
 | |
|                 }
 | |
|                 i += shift;
 | |
|             } else if (arg.equals("--shell")) {
 | |
|                 shell = true;
 | |
|                 i++;
 | |
|             } else {
 | |
|                 if (arg.equals("--")) i++;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|         String[] newargs = new String[args.length - i];
 | |
|         System.arraycopy(args, i, newargs, 0, newargs.length);
 | |
|         args = newargs;
 | |
| 
 | |
|         switch (action) {
 | |
|         case HASH_PASSWORD: {
 | |
|             String clear = null;
 | |
|             if (args.length > 0) clear = args[0];
 | |
| 
 | |
|             byte[] aeskey;
 | |
|             if (crypted && clear != null) {
 | |
|                 checkExisting(aeskeyfile);
 | |
|                 aeskey = readAeskeyfile(aeskeyfile);
 | |
|                 try {
 | |
|                     clear = AESEnc.sdecrypt(clear, aeskey);
 | |
|                 } catch (Exception e) {
 | |
|                     die(null, e);
 | |
|                 }
 | |
|             } else {
 | |
|                 aeskey = readAeskeyfile(aeskeyfile);
 | |
|             }
 | |
| 
 | |
|             if (codEtu && isCodEtu(clear)) {
 | |
|                 try {
 | |
|                     unlockEtuPasswordGroups(codEtuKey);
 | |
|                 } catch (Exception e) {
 | |
|                     die(null, e);
 | |
|                 }
 | |
|                 clear = getEtuPassword(clear);
 | |
|             }
 | |
| 
 | |
|             if (clear == null) {
 | |
|                 PasswordGenerator pg = new PasswordGenerator();
 | |
|                 clear = pg.generateJk(nbBlocks);
 | |
|             }
 | |
| 
 | |
|             String newCryptSalt = null;
 | |
|             byte[] newBinarySalt = null;
 | |
|             if (args.length <= 1) {
 | |
|                 hashAction = EHashAction.NEW;
 | |
|             } else if (hashAction == EHashAction.AUTO) {
 | |
|                 hashAction = EHashAction.CHECK_MATCH;
 | |
|             } else if (hashAction == EHashAction.SAME_OR_NEW) {
 | |
|                 i = 1;
 | |
|                 max = args.length;
 | |
|                 while (i < max) {
 | |
|                     String salt = args[i++];
 | |
|                     if (Password.isNormalizedFormat(salt)) {
 | |
|                         if (Password.isCryptScheme(salt)) {
 | |
|                             String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                             String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                     .getNormalized();
 | |
|                             if (salt.equals(crypt)) newCryptSalt = cryptSalt;
 | |
|                         } else if (Password.isSshaScheme(salt)) {
 | |
|                             byte[] sshaSalt = Salt.getSshaSalt(salt);
 | |
|                             String ssha = getPasswordBinarySalt(clear, Password.SSHA, sshaSalt)
 | |
|                                     .getNormalized();
 | |
|                             if (salt.equals(ssha)) newBinarySalt = sshaSalt;
 | |
|                         } else if (Password.isSmd5Scheme(salt)) {
 | |
|                             byte[] smd5Salt = Salt.getSmd5Salt(salt);
 | |
|                             String smd5 = getPasswordBinarySalt(clear, Password.SMD5, smd5Salt)
 | |
|                                     .getNormalized();
 | |
|                             if (salt.equals(smd5)) newBinarySalt = smd5Salt;
 | |
|                         }
 | |
|                     } else if (isHex(salt)) {
 | |
|                         byte[] binarySalt = fromHex(salt);
 | |
|                         String ssha = getPasswordBinarySalt(clear, Password.SSHA, binarySalt)
 | |
|                                 .getNormalized();
 | |
|                         String smd5 = getPasswordBinarySalt(clear, Password.SMD5, binarySalt)
 | |
|                                 .getNormalized();
 | |
|                         if (salt.length() >= 2) {
 | |
|                             String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                             String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                     .getNormalized();
 | |
|                             if (salt.equals(crypt)) newCryptSalt = cryptSalt;
 | |
|                         }
 | |
|                         if (salt.equals(ssha) || salt.equals(smd5)) newBinarySalt = binarySalt;
 | |
|                     } else {
 | |
|                         String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                         String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                 .getNormalized();
 | |
|                         if (salt.equals(crypt)) newCryptSalt = cryptSalt;
 | |
|                     }
 | |
|                 }
 | |
|                 hashAction = EHashAction.NEW;
 | |
|             }
 | |
| 
 | |
|             if (hashAction == EHashAction.NEW) {
 | |
|                 // Pas de salt, afficher simplement les versions cryptées des mots
 | |
|                 // de passe pour tous les schemes. Le salt est choisi au hasard pour
 | |
|                 // chaque mot de passe. Il est donc différent à chaque fois.
 | |
|                 Password p = getPasswordAnySalt(clear, null, null);
 | |
|                 String lm = null;
 | |
|                 String ntlm = null;
 | |
|                 try {
 | |
|                     lm = p.getLmHash();
 | |
|                     ntlm = p.getNtlmHash();
 | |
|                 } catch (Password.NotAvailableException e) {
 | |
|                 }
 | |
|                 String crypt = getPasswordCryptSalt(clear, Password.CRYPT, newCryptSalt)
 | |
|                         .getNormalized();
 | |
|                 String sha = getPasswordAnySalt(clear, Password.SHA, null).getNormalized();
 | |
|                 String xsha = getPasswordAnySalt(clear, Password.XSHA, null).getNormalized();
 | |
|                 String ssha = getPasswordBinarySalt(clear, Password.SSHA, newBinarySalt)
 | |
|                         .getNormalized();
 | |
|                 String md5 = getPasswordAnySalt(clear, Password.MD5, null).getNormalized();
 | |
|                 String smd5 = getPasswordBinarySalt(clear, Password.SMD5, newBinarySalt)
 | |
|                         .getNormalized();
 | |
|                 String wojmp = WOJavaMonitorPassword.encryptStringWithKey(clear, null);
 | |
|                 String aes = null;
 | |
|                 if (aeskey != null) {
 | |
|                     try {
 | |
|                         aes = AESEnc.sencrypt(clear, aeskey);
 | |
|                     } catch (Exception e) {
 | |
|                         die("Impossible de crypter avec AES", e);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 printvar("clear", clear, shell);
 | |
|                 printvar("lm", lm, shell);
 | |
|                 printvar("ntlm", ntlm, shell);
 | |
|                 printvar("crypt", crypt, shell);
 | |
|                 printvar("sha", sha, shell);
 | |
|                 printvar("xsha", xsha, shell);
 | |
|                 printvar("ssha", ssha, shell);
 | |
|                 printvar("md5", md5, shell);
 | |
|                 printvar("smd5", smd5, shell);
 | |
|                 printvar("wojmp", wojmp, shell);
 | |
|                 if (aes != null) printvar("aes", aes, shell);
 | |
|             } else if (hashAction == EHashAction.CHECK_MATCH) {
 | |
|                 // Afficher uniquement les versions cryptées des mots de passe avec
 | |
|                 // les schemes correspondant aux salts spécifiés, pour chacun des
 | |
|                 // salts spécifiés.
 | |
|                 printvar("clear", clear, shell);
 | |
|                 i = 1;
 | |
|                 max = args.length;
 | |
|                 while (i < max) {
 | |
|                     String salt = args[i++];
 | |
|                     if (Password.isNormalizedFormat(salt)) {
 | |
|                         if (Password.isCryptScheme(salt)) {
 | |
|                             String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                             String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                     .getNormalized();
 | |
|                             printvar("salt", cryptSalt, shell);
 | |
|                             printvar("crypt", crypt, shell);
 | |
|                             if (salt.equals(crypt)) printvar("match", "true", shell);
 | |
|                         } else if (Password.isSshaScheme(salt)) {
 | |
|                             byte[] sshaSalt = Salt.getSshaSalt(salt);
 | |
|                             String ssha = getPasswordBinarySalt(clear, Password.SSHA, sshaSalt)
 | |
|                                     .getNormalized();
 | |
|                             printvar("salt", toHex(sshaSalt), shell);
 | |
|                             printvar("ssha", ssha, shell);
 | |
|                             if (salt.equals(ssha)) printvar("match", "true", shell);
 | |
|                         } else if (Password.isSmd5Scheme(salt)) {
 | |
|                             byte[] smd5Salt = Salt.getSmd5Salt(salt);
 | |
|                             String smd5 = getPasswordBinarySalt(clear, Password.SMD5, smd5Salt)
 | |
|                                     .getNormalized();
 | |
|                             printvar("salt", toHex(smd5Salt), shell);
 | |
|                             printvar("smd5", smd5, shell);
 | |
|                             if (salt.equals(smd5)) printvar("match", "true", shell);
 | |
|                         } else {
 | |
|                             printvar("salt", salt + " !not supported", shell);
 | |
|                         }
 | |
|                     } else if (isHex(salt)) {
 | |
|                         byte[] binarySalt = fromHex(salt);
 | |
|                         String ssha = getPasswordBinarySalt(clear, Password.SSHA, binarySalt)
 | |
|                                 .getNormalized();
 | |
|                         String smd5 = getPasswordBinarySalt(clear, Password.SMD5, binarySalt)
 | |
|                                 .getNormalized();
 | |
|                         printvar("salt", toHex(binarySalt), shell);
 | |
|                         printvar("ssha", ssha, shell);
 | |
|                         printvar("smd5", smd5, shell);
 | |
|                         if (salt.length() >= 2) {
 | |
|                             String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                             String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                     .getNormalized();
 | |
|                             if (!salt.equals(cryptSalt)) printvar("salt", cryptSalt, shell);
 | |
|                             printvar("crypt", crypt, shell);
 | |
|                             if (salt.equals(crypt)) printvar("match", "true", shell);
 | |
|                         }
 | |
|                         if (salt.equals(ssha)) printvar("match", "true", shell);
 | |
|                         if (salt.equals(smd5)) printvar("match", "true", shell);
 | |
|                     } else {
 | |
|                         String cryptSalt = Salt.getCryptSalt(salt);
 | |
|                         String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt)
 | |
|                                 .getNormalized();
 | |
|                         printvar("salt", cryptSalt, shell);
 | |
|                         printvar("crypt", crypt, shell);
 | |
|                         if (salt.equals(crypt)) printvar("match", "true", shell);
 | |
|                     }
 | |
|                 }
 | |
|             } else {
 | |
|                 throw new Error("bug: hashAction==" + hashAction);
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         case GEN_AESKEY: {
 | |
|             if (aeskeyfile == null) {
 | |
|                 die("Vous devez spécifier l'option -f", null);
 | |
|             } else if (new File(aeskeyfile).exists()) {
 | |
|                 die(aeskeyfile + ": Refus d'écraser un fichier existant", null);
 | |
|             }
 | |
| 
 | |
|             String password = null;
 | |
|             if (args.length > 0) password = args[0];
 | |
|             String salt = null;
 | |
|             if (args.length > 1) salt = args[1];
 | |
| 
 | |
|             byte[] key = null;
 | |
|             try {
 | |
|                 if (password != null && salt != null) {
 | |
|                     key = AESEnc.genkey();
 | |
|                 } else {
 | |
|                     key = AESEnc.genkey(password, salt.getBytes(UTF_8), -1);
 | |
|                 }
 | |
|             } catch (Exception e) {
 | |
|                 die(null, e);
 | |
|             }
 | |
|             writeAeskeyfile(aeskeyfile, key);
 | |
| 
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         case SHOW_AESKEY: {
 | |
|             checkExisting(aeskeyfile);
 | |
|             byte[] key = readAeskeyfile(aeskeyfile);
 | |
|             println(AESEnc.getSkey(key));
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         case AES_ENCRYPT: {
 | |
|             checkExisting(aeskeyfile);
 | |
|             byte[] key = readAeskeyfile(aeskeyfile);
 | |
|             String sclear = null;
 | |
|             if (args.length > 0) sclear = args[0];
 | |
|             if (sclear != null) {
 | |
|                 try {
 | |
|                     println(AESEnc.sencrypt(sclear, key));
 | |
|                 } catch (Exception e) {
 | |
|                     die(null, e);
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         case AES_DECRYPT: {
 | |
|             checkExisting(aeskeyfile);
 | |
|             byte[] key = readAeskeyfile(aeskeyfile);
 | |
|             String scrypted = null;
 | |
|             if (args.length > 0) scrypted = args[0];
 | |
|             if (scrypted != null) {
 | |
|                 try {
 | |
|                     println(AESEnc.sdecrypt(scrypted, key));
 | |
|                 } catch (Exception e) {
 | |
|                     die(null, e);
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private static final Pattern SPACES = Pattern.compile("\\s+");
 | |
| 
 | |
|     private static final String BATCH_OPTION = "--batch";
 | |
| 
 | |
|     private static final String AFTER_COMMAND = BATCH_OPTION + "-after ";
 | |
| 
 | |
|     private static final int AFTER_COMMAND_STRIP = AFTER_COMMAND.length();
 | |
| 
 | |
|     public static void main(String[] args) {
 | |
|         upassword upassword = new upassword();
 | |
|         if (args.length > 0 && args[0].equals(BATCH_OPTION)) {
 | |
|             String after = null;
 | |
|             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 | |
|             try {
 | |
|                 while (true) {
 | |
|                     String line = br.readLine();
 | |
|                     if (line == null) break;
 | |
|                     if (line.startsWith("#")) {
 | |
|                         // Ignorer
 | |
|                     } else if (line.startsWith(AFTER_COMMAND)) {
 | |
|                         after = line.substring(AFTER_COMMAND_STRIP);
 | |
|                     } else {
 | |
|                         line = line.trim();
 | |
|                         if (line.equals("")) args = new String[0];
 | |
|                         else args = SPACES.split(line);
 | |
|                         upassword.run(args);
 | |
|                         if (after != null) println(after);
 | |
|                     }
 | |
|                 }
 | |
|             } catch (IOException e) {
 | |
|                 die(null, e);
 | |
|             }
 | |
| 
 | |
|         } else {
 | |
|             upassword.run(args);
 | |
|         }
 | |
|     }
 | |
| }
 |