美文网首页
Android 的几种AES实现

Android 的几种AES实现

作者: Il_mondo | 来源:发表于2018-06-05 08:20 被阅读3次
public class AESUtil{
   private static final String CipherMode = "AES/ECB/PKCS5Padding";

   private static SecretKeySpec createKey(String password) throws Exception {
       byte[] data;
       StringBuffer sb = new StringBuffer(32);
       sb.append(password);
       while (sb.length() < 32) {
           sb.append("0");
       }

       if (sb.length() > 32) {
           sb.setLength(32);
       }

       data = sb.toString().getBytes("UTF-8");
       return new SecretKeySpec(data, "AES");
   }

   public static byte[] encrypt(byte[] content, String password) throws Exception {
       SecretKeySpec key = createKey(password);
       System.out.println(key);
       Cipher cipher = Cipher.getInstance(CipherMode);
       cipher.init(Cipher.ENCRYPT_MODE, key);
       return cipher.doFinal(content);
   }

   public static String encrypt(String content, String password) throws Exception {
       byte[] data = content.getBytes("UTF-8");
       data = encrypt(data, password);
       return byte2hex(data);
   }

   public static byte[] decrypt(byte[] content, String password) throws Exception {
       SecretKeySpec key = createKey(password);
       Cipher cipher = Cipher.getInstance(CipherMode);
       cipher.init(Cipher.DECRYPT_MODE, key);
       return cipher.doFinal(content);

   }

   public static String decrypt(String content, String password) throws Exception {
       byte[] data = hex2byte(content);
       data = decrypt(data, password);
       if (data == null) return null;
       return new String(data, "UTF-8");
   }

   /*字节数组转成16进制字符串  */
   public static String byte2hex(byte[] b) { // 一个字节的数,
       StringBuilder sb = new StringBuilder(b.length * 2);
       String tmp;

       for (byte aB : b) {
           tmp = (Integer.toHexString(aB & 0XFF));
           if (tmp.length() == 1) {
               sb.append("0");
           }
           sb.append(tmp);
       }
       return sb.toString().toUpperCase();
   }

   private static byte[] hex2byte(String inputString) {
       if (inputString == null || inputString.length() < 2) {
           return new byte[0];
       }

       inputString = inputString.toLowerCase();
       int l = inputString.length() / 2;
       byte[] result = new byte[l];
       for (int i = 0; i < l; ++i) {
           String tmp = inputString.substring(2 * i, 2 * i + 2);
           result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
       }

       return result;
   }
}

public static String encrypt(String input, String key){
        byte[] crypted = null;
        try{
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            crypted = cipher.doFinal(input.getBytes());
        }catch(Exception e){
            System.out.println(e.toString());
        }

        return new String(Base64.encode(crypted, Base64.NO_WRAP));
    }

    public static String decrypt(String input, String key){
        byte[] output = null;
        try{
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skey);
            output = cipher.doFinal(Base64.decode(input, Base64.NO_WRAP));
        }catch(Exception e){
            System.out.println(e.toString());
        }
        return new String(output);
    }
//AESCrypt-ObjC uses CBC and PKCS7Padding
    private static final String AES_MODE = "AES/CBC/PKCS7Padding";
    private static final String CHARSET = "UTF-8";

    //AESCrypt-ObjC uses SHA-256 (and so a 256-bit key)
    private static final String HASH_ALGORITHM = "SHA-256";

    //AESCrypt-ObjC uses blank IV (not the best security, but the aim here is compatibility)
    private static final byte[] ivBytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


    /**
     * Generates SHA256 hash of the password which is used as key
     *
     * @param password used to generated key
     * @return SHA256 of the password
     */
    private static SecretKeySpec generateKey(final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        final MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM);
        byte[] bytes = password.getBytes("UTF-8");
        digest.update(bytes, 0, bytes.length);
        byte[] key = digest.digest();
        return new SecretKeySpec(key, "AES");
    }


    /**
     * Encrypt and encode message using 256-bit AES with key generated from password.
     *
     *
     * @param password used to generated key
     * @param message the thing you want to encrypt assumed String UTF-8
     * @return Base64 encoded CipherText
     * @throws GeneralSecurityException if problems occur during encryption
     */
    public static String encrypt(final String password, String message)
            throws GeneralSecurityException {

        try {
            final SecretKeySpec key = generateKey(password);
            byte[] cipherText = encrypt(key, ivBytes, message.getBytes(CHARSET));
            return Base64.encodeToString(cipherText, Base64.NO_WRAP);
        } catch (UnsupportedEncodingException e) {
            throw new GeneralSecurityException(e);
        }
    }

    /**
     * More flexible AES encrypt that doesn't encode
     * @param key AES key typically 128, 192 or 256 bit
     * @param iv Initiation Vector
     * @param message in bytes (assumed it's already been decoded)
     * @return Encrypted cipher text (not encoded)
     * @throws GeneralSecurityException if something goes wrong during encryption
     */
    public static byte[] encrypt(final SecretKeySpec key, final byte[] iv, final byte[] message)
            throws GeneralSecurityException {
        final Cipher cipher = Cipher.getInstance(AES_MODE);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        return cipher.doFinal(message);
    }


    /**
     * Decrypt and decode ciphertext using 256-bit AES with key generated from password
     *
     * @param password used to generated key
     * @param base64EncodedCipherText the encrpyted message encoded with base64
     * @return message in Plain text (String UTF-8)
     * @throws GeneralSecurityException if there's an issue decrypting
     */
    public static String decrypt(final String password, String base64EncodedCipherText)
            throws GeneralSecurityException {

        try {
            final SecretKeySpec key = generateKey(password);
            byte[] decodedCipherText = Base64.decode(base64EncodedCipherText, Base64.NO_WRAP);
            byte[] decryptedBytes = decrypt(key, ivBytes, decodedCipherText);
            return new String(decryptedBytes, CHARSET);
        } catch (UnsupportedEncodingException e) {
            throw new GeneralSecurityException(e);
        }
    }


    /**
     * More flexible AES decrypt that doesn't encode
     *
     * @param key AES key typically 128, 192 or 256 bit
     * @param iv Initiation Vector
     * @param decodedCipherText in bytes (assumed it's already been decoded)
     * @return Decrypted message cipher text (not encoded)
     * @throws GeneralSecurityException if something goes wrong during encryption
     */
    public static byte[] decrypt(final SecretKeySpec key, final byte[] iv, final byte[] decodedCipherText)
            throws GeneralSecurityException {
        final Cipher cipher = Cipher.getInstance(AES_MODE);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        return cipher.doFinal(decodedCipherText);
    }

    /**
     * Converts byte array to hexidecimal useful for logging and fault finding
     * @param bytes
     * @return
     */
    private static String bytesToHex(byte[] bytes) {
        final char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
                '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for (int j = 0; j < bytes.length; j++) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

相关文章

网友评论

      本文标题:Android 的几种AES实现

      本文链接:https://www.haomeiwen.com/subject/ugousftx.html