Kaynağa Gözat

[add]新增加密

pala 2 yıl önce
ebeveyn
işleme
09c0daf3e1

+ 214 - 0
common/src/main/java/com/atmob/common/crypto/Charsets.java

@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.atmob.common.crypto;
+
+import java.nio.charset.Charset;
+
+/**
+ * Charsets required of every implementation of the Java platform.
+ * <p/>
+ * From the Java documentation <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">
+ * Standard charsets</a>:
+ * <p>
+ * <cite>Every implementation of the Java platform is required to support the following character encodings. Consult the
+ * release documentation for your implementation to see if any other encodings are supported. Consult the release
+ * documentation for your implementation to see if any other encodings are supported. </cite>
+ * </p>
+ * <p/>
+ * <ul>
+ * <li><code>US-ASCII</code><br/>
+ * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set.</li>
+ * <li><code>ISO-8859-1</code><br/>
+ * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.</li>
+ * <li><code>UTF-8</code><br/>
+ * Eight-bit Unicode Transformation Format.</li>
+ * <li><code>UTF-16BE</code><br/>
+ * Sixteen-bit Unicode Transformation Format, big-endian byte order.</li>
+ * <li><code>UTF-16LE</code><br/>
+ * Sixteen-bit Unicode Transformation Format, little-endian byte order.</li>
+ * <li><code>UTF-16</code><br/>
+ * Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either order
+ * accepted on input, big-endian used on output.)</li>
+ * </ul>
+ *
+ * @version $Id: Charsets.java 1311751 2012-04-10 14:26:21Z ggregory $
+ * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+ * @since 2.3
+ */
+final class Charsets {
+    //
+    // This class should only contain Charset instances for required encodings. This guarantees that it will load
+    // correctly and without delay on all Java platforms.
+    //
+
+    /**
+     * CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_ISO_8859_1 = "ISO-8859-1";
+
+    /**
+     * <p>
+     * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode character set.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_US_ASCII = "US-ASCII";
+
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory initial byte-order mark
+     * (either order accepted on input, big-endian used on output)
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_UTF_16 = "UTF-16";
+
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, big-endian byte order.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_UTF_16BE = "UTF-16BE";
+
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, little-endian byte order.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_UTF_16LE = "UTF-16LE";
+
+    /**
+     * <p>
+     * Eight-bit Unicode Transformation Format.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final String ENCODING_UTF_8 = "UTF-8";
+    /**
+     * CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+    /**
+     * <p>
+     * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode character set.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset US_ASCII = Charset.forName("US-ASCII");
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory initial byte-order mark
+     * (either order accepted on input, big-endian used on output)
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset UTF_16 = Charset.forName("UTF-16");
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, big-endian byte order.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+    /**
+     * <p>
+     * Sixteen-bit Unicode Transformation Format, little-endian byte order.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+    /**
+     * <p>
+     * Eight-bit Unicode Transformation Format.
+     * </p>
+     * <p>
+     * Every implementation of the Java platform is required to support this character encoding.
+     * </p>
+     *
+     * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
+     */
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    /**
+     * Returns the given Charset or the default Charset if the given Charset is null.
+     *
+     * @param charset A charset or null.
+     * @return the given Charset or the default Charset if the given Charset is null
+     */
+    public static Charset toCharset(Charset charset) {
+        return charset == null ? Charset.defaultCharset() : charset;
+    }
+
+    /**
+     * Returns a Charset for the named charset. If the name is null, return the default Charset.
+     *
+     * @param charset The name of the requested charset, may be null.
+     * @return a Charset for the named charset
+     * @throws java.nio.charset.UnsupportedCharsetException If the named charset is unavailable
+     */
+    public static Charset toCharset(String charset) {
+        return charset == null ? Charset.defaultCharset() : Charset.forName(charset);
+    }
+}

+ 548 - 0
common/src/main/java/com/atmob/common/crypto/CryptoUtils.java

@@ -0,0 +1,548 @@
+package com.atmob.common.crypto;
+
+import android.util.Base64;
+import android.util.Log;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+
+/**
+ * 加密算法相关的工具方法
+ * Created by benson on 14/12/24.
+ */
+public final class CryptoUtils {
+    public static final String TAG = CryptoUtils.class.getSimpleName();
+    public static final String ENC_UTF8 = Charsets.ENCODING_UTF_8;
+
+    private CryptoUtils() {
+    }
+
+    static String getRandomString() {
+        SecureRandom random = new SecureRandom();
+        return String.valueOf(random.nextLong());
+    }
+
+    static byte[] getRandomBytes(int size) {
+        SecureRandom random = new SecureRandom();
+        byte[] bytes = new byte[size];
+        random.nextBytes(bytes);
+        return bytes;
+    }
+
+    static byte[] getRawBytes(String text) {
+        try {
+            return text.getBytes(ENC_UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return text.getBytes();
+        }
+    }
+
+    static String getString(byte[] data) {
+        try {
+            return new String(data, ENC_UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return new String(data);
+        }
+    }
+
+    static byte[] base64Decode(String text) {
+        return Base64.decode(text, Base64.NO_WRAP);
+    }
+
+    static String base64Encode(byte[] data) {
+        return Base64.encodeToString(data, Base64.NO_WRAP);
+    }
+
+    public static final class AES {
+        static final int ITERATION_COUNT_DEFAULT = 100;
+        static final int KEY_SIZE_DEFAULT = 256;
+        static final int IV_SIZE_DEFAULT = 16;
+        static final String KEY_AES_SPEC = "AES/CBC/PKCS7Padding";
+
+        public static String encrypt(String text) {
+            return encrypt(text, getSimplePassword(), getSimpleSalt(),
+                    getSimpleIV());
+        }
+
+        public static String decrypt(String text) {
+            return decrypt(text, getSimplePassword(), getSimpleSalt(),
+                    getSimpleIV());
+        }
+
+        public static byte[] encrypt(byte[] data) {
+            return encrypt(data, getSimplePassword(), getSimpleSalt(),
+                    getSimpleIV(), KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] decrypt(byte[] data) {
+            return decrypt(data, getSimplePassword(), getSimpleSalt(),
+                    getSimpleIV(), KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static String encrypt(String text, String password) {
+            return encrypt(text, password, getSimpleSalt(), getSimpleIV());
+        }
+
+        public static String decrypt(String text, String password) {
+            return decrypt(text, password, getSimpleSalt(), getSimpleIV());
+        }
+
+        public static byte[] encrypt(byte[] data, String password) {
+            return encrypt(data, password, getSimpleSalt(), getSimpleIV(),
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] decrypt(byte[] data, String password) {
+            return decrypt(data, password, getSimpleSalt(), getSimpleIV(),
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static String encrypt(String text, String password, byte[] salt) {
+            return encrypt(text, password, salt, getSimpleIV());
+        }
+
+        public static String decrypt(String text, String password, byte[] salt) {
+            return decrypt(text, password, salt, getSimpleIV());
+        }
+
+        public static byte[] encrypt(byte[] data, String password, byte[] salt) {
+            return encrypt(data, password, salt, getSimpleIV(),
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] decrypt(byte[] data, String password, byte[] salt) {
+            return decrypt(data, password, salt, getSimpleIV(),
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public static String encrypt(String text, String password, byte[] salt,
+                                     byte[] iv) {
+            byte[] data = getRawBytes(text);
+            byte[] encryptedData = encrypt(data, password, salt, iv,
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+            return base64Encode(encryptedData);
+        }
+
+        public static String decrypt(String text, String password, byte[] salt,
+                                     byte[] iv) {
+            byte[] encryptedData = base64Decode(text);
+            byte[] data = decrypt(encryptedData, password, salt, iv,
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+            return getString(data);
+        }
+
+        public static byte[] encrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv) {
+            return encrypt(data, password, salt, iv, KEY_SIZE_DEFAULT,
+                    ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] decrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv) {
+            return decrypt(data, password, salt, iv, KEY_SIZE_DEFAULT,
+                    ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] encrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv, int keySize) {
+            return encrypt(data, password, salt, iv, keySize,
+                    ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] decrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv, int keySize) {
+            return decrypt(data, password, salt, iv, keySize,
+                    ITERATION_COUNT_DEFAULT);
+        }
+
+        public static byte[] encrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv, int keySize, int iterationCount) {
+            return process(data, Cipher.ENCRYPT_MODE, password, salt, iv,
+                    keySize, iterationCount);
+        }
+
+        public static byte[] decrypt(byte[] data, String password, byte[] salt,
+                                     byte[] iv, int keySize, int iterationCount) {
+            return process(data, Cipher.DECRYPT_MODE, password, salt, iv,
+                    keySize, iterationCount);
+        }
+
+        /**
+         * AES encrypt function
+         *
+         * @param original
+         * @param key      16, 24, 32 bytes available
+         * @param iv       initial vector (16 bytes) - if null: ECB mode, otherwise:
+         *                 CBC mode
+         * @return
+         */
+        public static byte[] encrypt(byte[] original, byte[] key, byte[] iv) {
+            if (key == null
+                    || (key.length != 16 && key.length != 24 && key.length != 32)) {
+                return null;
+            }
+            if (iv != null && iv.length != 16) {
+                return null;
+            }
+
+            try {
+                SecretKeySpec keySpec = null;
+                Cipher cipher = null;
+                if (iv != null) {
+                    keySpec = new SecretKeySpec(key, KEY_AES_SPEC);
+                    cipher = Cipher.getInstance(KEY_AES_SPEC);
+                    cipher.init(Cipher.ENCRYPT_MODE, keySpec,
+                            new IvParameterSpec(iv));
+                } else // if(iv == null)
+                {
+                    keySpec = new SecretKeySpec(key, KEY_AES_SPEC);
+                    cipher = Cipher.getInstance(KEY_AES_SPEC);
+                    cipher.init(Cipher.ENCRYPT_MODE, keySpec);
+                }
+
+                return cipher.doFinal(original);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+        /**
+         * AES decrypt function
+         *
+         * @param encrypted
+         * @param key       16, 24, 32 bytes available
+         * @param iv        initial vector (16 bytes) - if null: ECB mode, otherwise:
+         *                  CBC mode
+         * @return
+         */
+        public static byte[] decrypt(byte[] encrypted, byte[] key, byte[] iv) {
+            if (key == null
+                    || (key.length != 16 && key.length != 24 && key.length != 32)) {
+                return null;
+            }
+            if (iv != null && iv.length != 16) {
+                return null;
+            }
+
+            try {
+                SecretKeySpec keySpec = null;
+                Cipher cipher = null;
+                if (iv != null) {
+                    keySpec = new SecretKeySpec(key, "AES/CBC/PKCS7Padding");// AES/ECB/PKCS5Padding
+                    cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
+                    cipher.init(Cipher.DECRYPT_MODE, keySpec,
+                            new IvParameterSpec(iv));
+                } else // if(iv == null)
+                {
+                    keySpec = new SecretKeySpec(key, "AES/ECB/PKCS7Padding");
+                    cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
+                    cipher.init(Cipher.DECRYPT_MODE, keySpec);
+                }
+
+                return cipher.doFinal(encrypted);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+        static byte[] process(byte[] data, int mode, String password,
+                              byte[] salt, byte[] iv, int keySize, int iterationCount) {
+            KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
+                    iterationCount, keySize);
+            try {
+                SecretKeyFactory keyFactory = SecretKeyFactory
+                        .getInstance("PBKDF2WithHmacSHA1");
+                byte[] keyBytes = keyFactory.generateSecret(keySpec)
+                        .getEncoded();
+                SecretKey key = new SecretKeySpec(keyBytes, "AES");
+                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+                IvParameterSpec ivParams = new IvParameterSpec(iv);
+                cipher.init(mode, key, ivParams);
+                return cipher.doFinal(data);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+        static String getSimplePassword() {
+            return "GZ9Gn2U5nhpea8hw";
+        }
+
+        static byte[] getSimpleSalt() {
+            return "rUiey8D2GNzV69Mp".getBytes();
+        }
+
+        static byte[] getSimpleIV() {
+            byte[] iv = new byte[AES.IV_SIZE_DEFAULT];
+            Arrays.fill(iv, (byte) 5);
+            return iv;
+        }
+    }
+
+    // http://nelenkov.blogspot.jp/2012/04/using-password-based-encryption-on.html
+    public static class AESCrypto {
+        private static final int ITERATION_COUNT_DEFAULT = 100;
+        private static final int ITERATION_COUNT_MIN = 10;
+        private static final int ITERATION_COUNT_MAX = 5000;
+        private static final int KEY_SIZE_DEFAULT = 256;
+        private static final int KEY_SIZE_MIN = 64;
+        private static final int KEY_SIZE_MAX = 1024;
+        private static final int IV_SIZE = 16;
+        private String password;
+        private byte[] salt;
+        private byte[] iv;
+        private int keySize;
+        private int iterCount;
+
+        public AESCrypto(String password) {
+            initialize(password, AES.getSimpleSalt(), AES.getSimpleIV(),
+                    KEY_SIZE_DEFAULT, ITERATION_COUNT_DEFAULT);
+        }
+
+        public AESCrypto(String password, byte[] salt) {
+            initialize(password, salt, AES.getSimpleIV(), KEY_SIZE_DEFAULT,
+                    ITERATION_COUNT_DEFAULT);
+        }
+
+        public AESCrypto(String password, int keySize, byte[] salt, byte[] iv) {
+            initialize(password, salt, iv, keySize, ITERATION_COUNT_DEFAULT);
+        }
+
+        private void initialize(String password, byte[] salt, byte[] iv,
+                                int keySize, int iterCount) {
+            this.password = password;
+            this.salt = salt;
+            this.iv = iv;
+            this.keySize = keySize;
+            this.iterCount = iterCount;
+        }
+
+        public String encrypt(String text) {
+            byte[] data = getRawBytes(text);
+            byte[] encryptedData = encrypt(data);
+            return base64Encode(encryptedData);
+        }
+
+        public byte[] encrypt(byte[] data) {
+            return process(data, Cipher.ENCRYPT_MODE);
+        }
+
+        public String decrypt(String text) {
+            byte[] encryptedData = base64Decode(text);
+            byte[] data = decrypt(encryptedData);
+            return getString(data);
+        }
+
+        public byte[] decrypt(byte[] encryptedData) {
+            return process(encryptedData, Cipher.DECRYPT_MODE);
+        }
+
+        private byte[] process(byte[] data, int mode) {
+            return AES.process(data, mode, password, salt, iv, keySize,
+                    iterCount);
+        }
+
+    }
+
+    public static final class HEX {
+
+        private static final char[] HEX_DIGITS = new char[]{'0', '1', '2',
+                '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+        private static final char[] FIRST_CHAR = new char[256];
+        private static final char[] SECOND_CHAR = new char[256];
+
+        static {
+            for (int i = 0; i < 256; i++) {
+                FIRST_CHAR[i] = HEX_DIGITS[(i >> 4) & 0xF];
+                SECOND_CHAR[i] = HEX_DIGITS[i & 0xF];
+            }
+        }
+
+        private static final byte[] DIGITS = new byte['f' + 1];
+
+        static {
+            for (int i = 0; i <= 'F'; i++) {
+                DIGITS[i] = -1;
+            }
+            for (byte i = 0; i < 10; i++) {
+                DIGITS['0' + i] = i;
+            }
+            for (byte i = 0; i < 6; i++) {
+                DIGITS['A' + i] = (byte) (10 + i);
+                DIGITS['a' + i] = (byte) (10 + i);
+            }
+        }
+
+        /**
+         * Quickly converts a byte array to a hexadecimal string representation.
+         *
+         * @param array byte array, possibly zero-terminated.
+         */
+        public static String encodeHex(byte[] array, boolean zeroTerminated) {
+            char[] cArray = new char[array.length * 2];
+
+            int j = 0;
+            for (int i = 0; i < array.length; i++) {
+                int index = array[i] & 0xFF;
+                if (index == 0 && zeroTerminated) {
+                    break;
+                }
+
+                cArray[j++] = FIRST_CHAR[index];
+                cArray[j++] = SECOND_CHAR[index];
+            }
+
+            return new String(cArray, 0, j);
+        }
+
+        /**
+         * Quickly converts a hexadecimal string to a byte array.
+         */
+        public static byte[] decodeHex(String hexString) {
+            int length = hexString.length();
+
+            if ((length & 0x01) != 0) {
+                throw new IllegalArgumentException("Odd number of characters.");
+            }
+
+            boolean badHex = false;
+            byte[] out = new byte[length >> 1];
+            for (int i = 0, j = 0; j < length; i++) {
+                int c1 = hexString.charAt(j++);
+                if (c1 > 'f') {
+                    badHex = true;
+                    break;
+                }
+
+                final byte d1 = DIGITS[c1];
+                if (d1 == -1) {
+                    badHex = true;
+                    break;
+                }
+
+                int c2 = hexString.charAt(j++);
+                if (c2 > 'f') {
+                    badHex = true;
+                    break;
+                }
+
+                final byte d2 = DIGITS[c2];
+                if (d2 == -1) {
+                    badHex = true;
+                    break;
+                }
+
+                out[i] = (byte) (d1 << 4 | d2);
+            }
+
+            if (badHex) {
+                throw new IllegalArgumentException(
+                        "Invalid hexadecimal digit: " + hexString);
+            }
+
+            return out;
+        }
+    }
+
+    public static final class HASH {
+        private static final String MD5 = "MD5";
+        private static final String SHA_1 = "SHA-1";
+        private static final String SHA_256 = "SHA-256";
+        private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4',
+                '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+        private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4',
+                '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+        public static String md5(byte[] data) {
+            return new String(encodeHex(md5Bytes(data)));
+        }
+
+        public static String md5(String text) {
+            return new String(encodeHex(md5Bytes(getRawBytes(text))));
+        }
+
+        public static String md5(InputStream is) {
+            try {
+                return md5(IOUtils.readBytes(is));
+            } catch (Exception e) {
+                Log.w("exception", e);
+                return "";
+            } finally {
+                IOUtils.closeQuietly(is);
+            }
+        }
+
+        public static byte[] md5Bytes(byte[] data) {
+            return getDigest(MD5).digest(data);
+        }
+
+        public static String sha1(byte[] data) {
+            return new String(encodeHex(sha1Bytes(data)));
+        }
+
+        public static String sha1(String text) {
+            return new String(encodeHex(sha1Bytes(getRawBytes(text))));
+        }
+
+        public static byte[] sha1Bytes(byte[] data) {
+            return getDigest(SHA_1).digest(data);
+        }
+
+        public static String sha256(byte[] data) {
+            return new String(encodeHex(sha256Bytes(data)));
+        }
+
+        public static String sha256(String text) {
+            return new String(encodeHex(sha256Bytes(getRawBytes(text))));
+        }
+
+        public static byte[] sha256Bytes(byte[] data) {
+            return getDigest(SHA_256).digest(data);
+        }
+
+        private static MessageDigest getDigest(String algorithm) {
+            try {
+                return MessageDigest.getInstance(algorithm);
+            } catch (NoSuchAlgorithmException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        private static char[] encodeHex(byte[] data) {
+            return encodeHex(data, true);
+        }
+
+        private static char[] encodeHex(byte[] data, boolean toLowerCase) {
+            return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+        }
+
+        private static char[] encodeHex(byte[] data, char[] toDigits) {
+            int l = data.length;
+            char[] out = new char[l << 1];
+            for (int i = 0, j = 0; i < l; i++) {
+                out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
+                out[j++] = toDigits[0x0F & data[i]];
+            }
+            return out;
+        }
+
+    }
+
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1578 - 0
common/src/main/java/com/atmob/common/crypto/IOUtils.java


+ 159 - 0
common/src/main/java/com/atmob/common/crypto/StringBuilderWriter.java

@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.atmob.common.crypto;
+
+import java.io.Serializable;
+import java.io.Writer;
+
+/**
+ * {@link Writer} implementation that outputs to a {@link StringBuilder}.
+ * <p/>
+ * <strong>NOTE:</strong> This implementation, as an alternative to
+ * <code>java.io.StringWriter</code>, provides an <i>un-synchronized</i>
+ * (i.e. for use in a single thread) implementation for better performance.
+ * For safe usage with multiple {@link Thread}s then
+ * <code>java.io.StringWriter</code> should be used.
+ *
+ * @version $Id: StringBuilderWriter.java 1304052 2012-03-22 20:55:29Z ggregory $
+ * @since 2.0
+ */
+final class StringBuilderWriter extends Writer implements Serializable {
+
+    private final StringBuilder builder;
+
+    /**
+     * Construct a new {@link StringBuilder} instance with default capacity.
+     */
+    public StringBuilderWriter() {
+        this.builder = new StringBuilder();
+    }
+
+    /**
+     * Construct a new {@link StringBuilder} instance with the specified capacity.
+     *
+     * @param capacity The initial capacity of the underlying {@link StringBuilder}
+     */
+    public StringBuilderWriter(int capacity) {
+        this.builder = new StringBuilder(capacity);
+    }
+
+    /**
+     * Construct a new instance with the specified {@link StringBuilder}.
+     *
+     * @param builder The String builder
+     */
+    public StringBuilderWriter(StringBuilder builder) {
+        this.builder = builder != null ? builder : new StringBuilder();
+    }
+
+    /**
+     * Closing this writer has no effect.
+     */
+    @Override
+    public void close() {
+    }
+
+    /**
+     * Flushing this writer has no effect.
+     */
+    @Override
+    public void flush() {
+    }
+
+    /**
+     * Write a portion of a character array to the {@link StringBuilder}.
+     *
+     * @param value  The value to write
+     * @param offset The index of the first character
+     * @param length The number of characters to write
+     */
+    @Override
+    public void write(char[] value, int offset, int length) {
+        if (value != null) {
+            builder.append(value, offset, length);
+        }
+    }
+
+    /**
+     * Write a String to the {@link StringBuilder}.
+     *
+     * @param value The value to write
+     */
+    @Override
+    public void write(String value) {
+        if (value != null) {
+            builder.append(value);
+        }
+    }
+
+    /**
+     * Append a single character to this Writer.
+     *
+     * @param value The character to append
+     * @return This writer instance
+     */
+    @Override
+    public Writer append(char value) {
+        builder.append(value);
+        return this;
+    }
+
+    /**
+     * Append a character sequence to this Writer.
+     *
+     * @param value The character to append
+     * @return This writer instance
+     */
+    @Override
+    public Writer append(CharSequence value) {
+        builder.append(value);
+        return this;
+    }
+
+    /**
+     * Append a portion of a character sequence to the {@link StringBuilder}.
+     *
+     * @param value The character to append
+     * @param start The index of the first character
+     * @param end   The index of the last character + 1
+     * @return This writer instance
+     */
+    @Override
+    public Writer append(CharSequence value, int start, int end) {
+        builder.append(value, start, end);
+        return this;
+    }
+
+    /**
+     * Return the underlying builder.
+     *
+     * @return The underlying builder
+     */
+    public StringBuilder getBuilder() {
+        return builder;
+    }
+
+    /**
+     * Returns {@link StringBuilder#toString()}.
+     *
+     * @return The contents of the String builder.
+     */
+    @Override
+    public String toString() {
+        return builder.toString();
+    }
+}

+ 1 - 1
common/src/main/java/com/atmob/common/thread/ThreadPoolUtil.java

@@ -25,7 +25,7 @@ public final class ThreadPoolUtil {
 
         @Override
         public Thread newThread(Runnable r) {
-            return new Thread(r, "NetWork Dispatcher #" + mCount.getAndIncrement());
+            return new Thread(r, "Thread Dispatcher #" + mCount.getAndIncrement());
         }
     };